我正在尝试在单个图形中的一行中绘制两个3D线框图和一个色条。为了在线框上应用颜色渐变,我遵循了此Stackoverflow Answer。因此,我不得不生成独立的颜色条。由于我使用的是tight_layout
,因此彩条占用了整个高度,并且显示的宽度很大。
到目前为止,我找不到控制颜色条大小的任何解决方案。我尝试更改网格的width_ratio
,但宽度保持不变。似乎无法在tight layout
中调整高度。
我的绘图代码如下。在这方面的任何帮助,我将不胜感激。
def plot_signature(hh, hv, vh, vv, wireframe=False):
x_c, y_c, z_c = synthesize(hh=hh, hv=hv, vh=vh, vv=vv, channel=False)
x_x, y_x, z_x = synthesize(hh=hh, hv=hv, vh=vh, vv=vv, channel=True)
xticks = np.linspace(0, 180, 13)
yticks = np.linspace(-45, 45, 7)
zticks = np.linspace(0, 1, 11)
xt_labels = np.core.defchararray.add(xticks.astype(int).astype(str), u"\u00b0")
yt_labels = np.core.defchararray.add(yticks.astype(int).astype(str), u"\u00b0")
plt.ion()
fig = plt.figure(tight_layout=True)
grid = fig.add_gridspec(nrows=1, ncols=3, width_ratios=[1, 10, 10])
ax_cbar = fig.add_subplot(grid[0, 0])
ax_cpol = fig.add_subplot(grid[0, 1], projection='3d')
ax_xpol = fig.add_subplot(grid[0, 2], projection='3d')
ax_cpol.set_xlim([0, 180])
ax_cpol.set_ylim([-45, 45])
ax_cpol.set_zlim([0, 1])
ax_xpol.set_xlim([0, 180])
ax_xpol.set_ylim([-45, 45])
ax_xpol.set_zlim([0, 1])
cfont = {'fontname':'CMU Serif'}
color_map = cm.rainbow
if wireframe:
norm_c = plt.Normalize(z_c.min(), z_c.max())
norm_x = plt.Normalize(z_x.min(), z_x.max())
colors_c = color_map(norm_c(z_c))
colors_x = color_map(norm_c(z_x))
rcount_c, ccount_c, _ = colors_c.shape
rcount_x, ccount_x, _ = colors_x.shape
pfig_c = ax_cpol.plot_surface(x_c, y_c, z_c, rcount=rcount_c, ccount=ccount_c, facecolors=colors_c, shade=False)
pfig_x = ax_xpol.plot_surface(x_x, y_x, z_x, rcount=rcount_x, ccount=ccount_x, facecolors=colors_x, shade=False)
pfig_c.set_facecolor((0, 0, 0, 0))
pfig_x.set_facecolor((0, 0, 0, 0))
else:
ax_cpol.plot_surface(x_c, y_c, z_c, cmap=color_map, linewidth=0, antialiased=True)
ax_xpol.plot_surface(x_x, y_x, z_x, cmap=color_map, linewidth=0, antialiased=True)
ax_cpol.set_xticks(xticks)
ax_xpol.set_xticks(xticks)
ax_cpol.set_xticklabels(xt_labels)
ax_xpol.set_xticklabels(xt_labels)
ax_cpol.set_yticks(yticks)
ax_xpol.set_yticks(yticks)
ax_cpol.set_yticklabels(yt_labels)
ax_xpol.set_yticklabels(yt_labels)
ax_cpol.set_xlabel('Orientation Angle ($\psi$)', labelpad=16, fontsize=16, **cfont)
ax_xpol.set_xlabel('Orientation Angle ($\psi$)', labelpad=16, fontsize=16, **cfont)
ax_cpol.set_ylabel('Ellipticity Angle ($\chi$)', labelpad=16, fontsize=16, **cfont)
ax_xpol.set_ylabel('Ellipticity Angle ($\chi$)', labelpad=16, fontsize=16, **cfont)
ax_cpol.set_zlabel("Relative Intensity", labelpad=16, fontsize=16, **cfont)
ax_xpol.set_zlabel("Relative Intensity", labelpad=16, fontsize=16, **cfont)
ax_cpol.set_zticks(zticks)
ax_xpol.set_zticks(zticks)
ax_cpol.set_title("Co-pol Signature", fontsize=20, pad=20, **cfont)
ax_xpol.set_title("Cross-pol Signature", fontsize=20, pad=20, **cfont)
cb_norm = mpl.colors.Normalize(vmin=0,vmax=1)
cb_ticks = np.linspace(0.0, 1.0, 11)
cb = mpl.colorbar.ColorbarBase(
ax_cbar,cmap=color_map,
norm=cb_norm,ticks=cb_ticks,
label='Color Map',
orientation='vertical'
)
cb_label = cb.ax.yaxis.label
cb.ax.yaxis.labelpad = 10
custom_font = mpl.font_manager.FontProperties(family='CMU Serif', size=12)
cb_label.set_font_properties(custom_font)
plt.show()
当前情节如下:
但是,我希望它类似于以下内容:
答案 0 :(得分:1)
当前您使用的是1 x 3网格。
考虑使用3 x 3网格,其中3D图覆盖所有三行,而颜色条仅位于第二行。
请注意,颜色条当然应该使用与曲面图相同的归一化。表面图应使用相同的归一化。简短:应该进行一次归一化,否则绘图会传达错误的信息。
最后,这里不需要使用ColorbarBase
;更好地使用
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([]) # still needed for matplotlib <= 3.0
fig.colorbar(sm, cax=cax)
这可能允许使用不同的选项来缩小颜色栏。
理想情况下,答案会把所有这些都变成代码,但是问题中没有可运行的代码可以轻松实现。
答案 1 :(得分:0)
ImportanceOfBeingErnes已经发布了正确的工作解决方案。我将展示他的答案的实现。请注意,这次我用颜色图实现了线框图,有点不同(Source)。
def plot_signature(hh, hv, vh, vv, wireframe=False):
x_c, y_c, z_c = synthesize(
hh=hh,
hv=hv,
vh=vh,
vv=vv,
channel=False
)
x_x, y_x, z_x = synthesize(
hh=hh,
hv=hv,
vh=vh,
vv=vv,
channel=True
)
xticks = np.linspace(0, 180, 13)
yticks = np.linspace(-45, 45, 7)
zticks = np.linspace(0, 1, 11)
xt_labels = np.core.defchararray.add(
xticks.astype(int).astype(str),
u"\u00b0"
)
yt_labels = np.core.defchararray.add(
yticks.astype(int).astype(str),
u"\u00b0"
)
plt.ion()
fig = plt.figure(num='Polarimetric Signatures', tight_layout=True)
gs_root = mpl.gridspec.GridSpec(
nrows=1,
ncols=3,
width_ratios=[1, 10, 10]
)
cb_gs = mpl.gridspec.GridSpecFromSubplotSpec(
nrows=3,
ncols=3,
height_ratios=[2, 5, 2],
width_ratios=[1.1, 0.8, 1.1],
subplot_spec=gs_root[0]
)
ax_cbar = fig.add_subplot(cb_gs[1, 1])
ax_cpol = fig.add_subplot(gs_root[0, 1], projection='3d')
ax_xpol = fig.add_subplot(gs_root[0, 2], projection='3d')
ax_cpol.set_xlim([0, 180])
ax_cpol.set_ylim([-45, 45])
ax_cpol.set_zlim([0, 1])
ax_xpol.set_xlim([0, 180])
ax_xpol.set_ylim([-45, 45])
ax_xpol.set_zlim([0, 1])
cfont = {'fontname': 'CMU Serif'}
color_map = cm.rainbow
if wireframe:
wire_c = ax_cpol.plot_wireframe(
x_c,
y_c,
z_c,
rstride=1,
cstride=2
)
nx_c, ny_c, _ = np.shape(wire_c._segments3d)
wire_c_x = np.array(wire_c._segments3d)[:, :, 0].ravel()
wire_c_y = np.array(wire_c._segments3d)[:, :, 1].ravel()
wire_c_z = np.array(wire_c._segments3d)[:, :, 2].ravel()
wire_c.remove()
wire_c_x1 = np.vstack([wire_c_x, np.roll(wire_c_x, 1)])
wire_c_y1 = np.vstack([wire_c_y, np.roll(wire_c_y, 1)])
wire_c_z1 = np.vstack([wire_c_z, np.roll(wire_c_z, 1)])
to_delete = np.arange(0, (nx_c * ny_c), ny_c)
wire_c_x1 = np.delete(wire_c_x1, to_delete, axis=1)
wire_c_y1 = np.delete(wire_c_y1, to_delete, axis=1)
wire_c_z1 = np.delete(wire_c_z1, to_delete, axis=1)
scalars_c = np.delete(wire_c_z, to_delete)
segs_c = [
list(zip(x_c, y_c, z_c))
for x_c, y_c, z_c in zip(wire_c_x1.T, wire_c_y1.T, wire_c_z1.T)
]
my_wire_c = art3d.Line3DCollection(segs_c, cmap=color_map)
my_wire_c.set_array(scalars_c)
ax_cpol.add_collection(my_wire_c)
wire_x = ax_xpol.plot_wireframe(
x_x,
y_x,
z_x,
rstride=1,
cstride=2
)
nx_x, ny_x, _ = np.shape(wire_x._segments3d)
wire_x_x = np.array(wire_x._segments3d)[:, :, 0].ravel()
wire_x_y = np.array(wire_x._segments3d)[:, :, 1].ravel()
wire_x_z = np.array(wire_x._segments3d)[:, :, 2].ravel()
wire_x.remove()
wire_x_x1 = np.vstack([wire_x_x, np.roll(wire_x_x, 1)])
wire_x_y1 = np.vstack([wire_x_y, np.roll(wire_x_y, 1)])
wire_x_z1 = np.vstack([wire_x_z, np.roll(wire_x_z, 1)])
to_delete = np.arange(0, (nx_x * ny_x), ny_x)
wire_x_x1 = np.delete(wire_x_x1, to_delete, axis=1)
wire_x_y1 = np.delete(wire_x_y1, to_delete, axis=1)
wire_x_z1 = np.delete(wire_x_z1, to_delete, axis=1)
scalars_x = np.delete(wire_x_z, to_delete)
segs_x = [
list(zip(x_x, y_x, z_x))
for x_x, y_x, z_x in zip(wire_x_x1.T, wire_x_y1.T, wire_x_z1.T)
]
my_wire_x = art3d.Line3DCollection(segs_x, cmap=color_map)
my_wire_x.set_array(scalars_x)
ax_xpol.add_collection(my_wire_x)
cb_norm = mpl.colors.Normalize(vmin=0, vmax=1)
cb_ticks = np.linspace(0.0, 1.0, 11)
cb = plt.colorbar(
my_wire_c,
ax_cbar, cmap=color_map,
norm=cb_norm, ticks=cb_ticks,
orientation='vertical',
label="Color Map",
ticklocation='left'
)
cb_label = cb.ax.yaxis.label
cb.ax.yaxis.labelpad = 10
custom_font = mpl.font_manager.FontProperties(
family='CMU Serif',
size=12
)
cb_label.set_font_properties(custom_font)
else:
ax_cpol.plot_surface(
x_c,
y_c,
z_c,
cmap=color_map,
linewidth=0,
antialiased=True
)
ax_xpol.plot_surface(
x_x,
y_x,
z_x,
cmap=color_map,
linewidth=0,
antialiased=True
)
ax_cpol.set_xticks(xticks)
ax_xpol.set_xticks(xticks)
ax_cpol.set_xticklabels(xt_labels)
ax_xpol.set_xticklabels(xt_labels)
ax_cpol.set_yticks(yticks)
ax_xpol.set_yticks(yticks)
ax_cpol.set_yticklabels(yt_labels)
ax_xpol.set_yticklabels(yt_labels)
ax_cpol.set_xlabel(
'Orientation Angle ($\psi$)',
labelpad=16,
fontsize=16,
**cfont
)
ax_xpol.set_xlabel(
'Orientation Angle ($\psi$)',
labelpad=16,
fontsize=16,
**cfont)
ax_cpol.set_ylabel(
'Ellipticity Angle ($\chi$)',
labelpad=16,
fontsize=16,
**cfont
)
ax_xpol.set_ylabel(
'Ellipticity Angle ($\chi$)',
labelpad=16,
fontsize=16,
**cfont
)
ax_cpol.set_zlabel(
"Relative Intensity",
labelpad=16,
fontsize=16,
**cfont
)
ax_xpol.set_zlabel(
"Relative Intensity",
labelpad=16,
fontsize=16,
**cfont
)
ax_cpol.set_zticks(zticks)
ax_xpol.set_zticks(zticks)
ax_cpol.set_title(
"Co-pol Signature",
fontsize=20,
pad=20,
**cfont
)
ax_xpol.set_title(
"Cross-pol Signature",
fontsize=20,
pad=20,
**cfont
)
plt.show()
return 0
电流输出如下所示: