Python 3.x 如何在matplotlib中的紧密布局下调整独立色条的大小(高度和宽度)
我试图在一个图形中绘制两个3D线框图和一个颜色条,为了在线框上应用颜色渐变,我遵循以下步骤。因此,我不得不生成独立的颜色条。由于我使用的是Python 3.x 如何在matplotlib中的紧密布局下调整独立色条的大小(高度和宽度),python-3.x,matplotlib,Python 3.x,Matplotlib,我试图在一个图形中绘制两个3D线框图和一个颜色条,为了在线框上应用颜色渐变,我遵循以下步骤。因此,我不得不生成独立的颜色条。由于我使用的是tight_布局颜色条占据了整个高度,并且显示的宽度很大 到目前为止,我还没有找到任何控制色条大小的解决方案。我尝试更改网格的宽度\u比率,但宽度保持不变。在紧凑的布局中,似乎无法调整高度 我的绘图代码如下所示。在这方面,如有任何帮助,我将不胜感激 def plot_signature(hh, hv, vh, vv, wireframe=False):
tight_布局
颜色条占据了整个高度,并且显示的宽度很大
到目前为止,我还没有找到任何控制色条大小的解决方案。我尝试更改网格的宽度\u比率
,但宽度保持不变。在紧凑的布局中,似乎无法调整高度
我的绘图代码如下所示。在这方面,如有任何帮助,我将不胜感激
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()
当前,该绘图如下所示:
但是,我希望它如下所示:
当前您使用的是1 x 3网格
考虑使用3 x 3网格,其中3D打印覆盖所有三行,而颜色栏仅位于第二行
请注意,颜色栏当然应该使用与曲面打印相同的规格化。曲面图应该使用相同的规格化。简而言之:应该有一个单一的标准化,否则情节会传达错误的信息
最后,这里不需要使用colorbase
;更好地利用
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([]) # still needed for matplotlib <= 3.0
fig.colorbar(sm, cax=cax)
sm=plt.cm.scalarMapable(cmap=cmap,norm=norm)
sm.set_数组([])#仍然需要matplotlib已发布正确的工作解决方案。我将展示他的答案的实施情况。请注意,这次我用colormap()实现了线框图,但有点不同()
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
电流输出如下所示:
尝试使用colorbar的收缩
、方面
和分数
参数,我使用的是对象,因为它是一个独立的colorbar。不幸的是,ColorbarBase对象不支持收缩
、方面
或分数
(请参见答案:);它继承父轴的属性。在本例中,使用ax
参数设置您自己的颜色栏:谢谢。我正准备写一本书,这正是我昨天自己想出的解决方案。首先,我尝试了第二种方法。E使用colorbar
而不是colorbase
,我做的有点不同。但是收缩
,分数
等都不起作用。接下来,我使用GridSpec
和SubplotSpec
对图形空间进行了划分,正如您所示。现在很完美。我将张贴我的代码以供参考。