如何在matplotlib中创建非线性色条标记

2024-09-30 19:28:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用colorcet中的“hot\r”和“kbc”创建了一个自定义发散颜色图,如下所示:

def lin_to_diverge(cmap1, cmap2, cmapname):

    in1 = plt.cm.get_cmap(cmap1)(np.linspace(0, 1, 129))
    in2 = plt.cm.get_cmap(cmap2)(np.linspace(0, 1, 129))

    combine = np.vstack((in1, in2))
    outmap = mcolors.LinearSegmentedColormap.from_list(cmapname, combine)
    return outmap

我正在绘制全球等高线图上的一些数据。这次行动的勇气如下:

    cmap = lin_to_diverge(cc.cm.kbc, 'hot_r', 'colorcet')

    # plot a contourplot of trends on a global map
    ax.set_global()
    ax.coastlines(linewidth=0.5)
    cbarticks = np.arange(-6.0, 7.0, 1)
    ax3.set_xticks([0, 90, 180, -90, -180], crs=ccrs.PlateCarree())
    ax4.set_xticks([0, 90, 180, -90, -180], crs=ccrs.PlateCarree())
    ax1.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())
    ax3.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())
    ax.contourf(xx, yy, trends, cbarticks, cmap=cmap, levels=levels_def, vmin=-12, vmax=12,
                transform=ccrs.PlateCarree(), extend='both')  # ,norm=colors.SymLogNorm(linthresh=0.03, linscale=0.03,vmin=-12, vmax=12)

    def_levels = [np.nanmin(insignificant1), 0, np.nanmax(insignificant1)]
    ax.contourf(xx, yy, insignificant1, cbarticks, levels=def_levels, hatches=["XXXXXX", ""], linewidth='0', alpha=0,
                transform=ccrs.PlateCarree(), vmin=-12, vmax=12)
    def_levels2 = [np.nanmin(insignificant2), 0, np.nanmax(insignificant2)]
    ax.contourf(xx, yy, insignificant2, cbarticks, levels=def_levels2, hatches=["//////", ""], alpha=0,
                transform=ccrs.PlateCarree(), vmin=-12, vmax=12)
    # plt.savefig(outdir + file+"_global_day_"+str(day)+".pdf", bbox_inches='tight', dpi=500)
    # plt.savefig(outdir + file+"_global_day_"+str(day)+".png")

fig.text(0.02, 0.5, 'Latitude', ha='center', va='center', rotation='vertical')
fig.text(0.48, 0.04, 'Longitude', ha='center', va='center')
ax1.set_title('Day 90')
ax2.set_title('Day 180')
ax3.set_title('Day 270')
ax4.set_title('Day 360')

# orig_cmap = mpl.cm.seismic
# shrunk_cmap = scm(orig_cmap, start=-12, midpoint=0.75, stop=12, name='shrunk')

m = plt.cm.ScalarMappable(cmap=cmap)
m.set_array(trends)
m.set_clim(-12, 12)
fig.subplots_adjust(bottom=0.07, top=1, left=0.1, right=0.9,
                    wspace=0.11, hspace=-0.1)
cb_ax = fig.add_axes([0.9, 0.05, 0.02, 0.92])

# cbarticks = [-12, -6., -5., -4., -3., -2., -1.,  0.,  1.,  2.,  3.,  4.,  5.,  6., 12]
ticks = np.linspace(-12, 12, 9)

cbar = fig.colorbar(m, cax=cb_ax, ticks=ticks)
# cbar.ax.set_yticklabels(cbarticks)
cbar.set_label('Trend [DU/year]')

plt.show()
plt.close()

我希望在颜色栏中添加非线性记号,特别是在不修改颜色图的情况下,因为当前绘图上的颜色分布是正确的。最好的方法是什么?我是否应该专门为colorbar创建一个新的colormap并从中导出刻度?我不想改变颜色条目前的样子。我希望有更多的值在零附近,即[3,2,1.5,0.5,0,-0.5,-1.5,-2,-3],但是这些值应该分布得更多,而12和-12当前所在的位置应该保持不变。因此,接近零的滴答声应该更分散。你知道吗

以下是根据上述脚本生成的数字:


Tags: 颜色defnpfigcmpltaxglobal
1条回答
网友
1楼 · 发布于 2024-09-30 19:28:59

把我的问题弄明白了- 这个问题的解决方案是使用SymLogNorm将数值缩放到接近零的位置,从而在零标记附近获得更多色条标记的期望结果。SymLogNorm也可以用于负值,所以它回答了这个问题。你知道吗

可以使用函数的vmin和vmax参数更改其他参数,如下所示:

matplotlib.colors.SymLogNorm(linthresh, linscale=1.0, vmin=None, vmax=None, clip=False)

我通过添加一个“norm=”参数在上述代码中实现了这一点,如下所示:

ax.contourf(xx, yy, trends, cbarticks, cmap=cmap, levels=levels_def,
                norm=mpcol.SymLogNorm(linthresh=0.03, linscale=0.03),
                transform=ccrs.PlateCarree(), extend='both')

然后,我编辑了颜色条的勾号参数,因为对数刻度将它们揉成一团:

cbarticks = [-12, -4, -2, -1, -0.5, -0.3, -0.2, -0.1, 0, 0.1, 0.2, 0.3, 0.5, 1, 2, 4, 12]
ticks = np.linspace(-12, 12, 9)
cbar = fig.colorbar(m, cax=cb_ax, ticks=cbarticks)
cbar.ax.set_yticklabels(cbarticks)

这就产生了这些情节:

SymLogNorm scaling of first plot in question

SymLogNorm scaling of second plot in question

相关问题 更多 >