Python 3.x 如何在matplotlib中的紧密布局下调整独立色条的大小(高度和宽度)

Python 3.x 如何在matplotlib中的紧密布局下调整独立色条的大小(高度和宽度),python-3.x,matplotlib,Python 3.x,Matplotlib,我试图在一个图形中绘制两个3D线框图和一个颜色条,为了在线框上应用颜色渐变,我遵循以下步骤。因此,我不得不生成独立的颜色条。由于我使用的是tight_布局颜色条占据了整个高度,并且显示的宽度很大 到目前为止,我还没有找到任何控制色条大小的解决方案。我尝试更改网格的宽度\u比率,但宽度保持不变。在紧凑的布局中,似乎无法调整高度 我的绘图代码如下所示。在这方面,如有任何帮助,我将不胜感激 def plot_signature(hh, hv, vh, vv, wireframe=False):

我试图在一个图形中绘制两个3D线框图和一个颜色条,为了在线框上应用颜色渐变,我遵循以下步骤。因此,我不得不生成独立的颜色条。由于我使用的是
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
对图形空间进行了划分,正如您所示。现在很完美。我将张贴我的代码以供参考。