python - 如何在 matplotlib 中创建非线性颜色条刻度
问题描述
我使用 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()
我希望在颜色条上添加非线性刻度,特别是在不修改颜色图的情况下,因为绘图上的当前颜色分布是正确的。做这个的最好方式是什么?我应该专门为颜色条创建一个新的颜色图并从中派生刻度吗?不过,我现在不想改变颜色条的外观。我希望有更多接近零的值,即 [3, 2, 1.5, 0.5, 0, -0.5, -1.5, -2, -3],但是这些值应该分散得更多,而 where 的位置当前的 12 和 -12 应该保持不变。因此,接近零的刻度应该分散得更多。
以下是上述脚本生成的数字:
解决方案
想出了我的问题 - 这个问题的解决方案是使用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)
这产生了这些图:
推荐阅读
- javascript - ASP.NET MVC ajax post 函数发送空值
- r - 将我的日志(值)添加到 R 中的数据框
- java - 我可以动态地制作表格布局吗?有没有一种方法可以占用我需要多少行和列?
- python - 为什么我的脚本目录不在 Python sys.path 中?
- packet-sniffers - 如何在 Contiki 中偷听邻居 mote Tx/Rx?
- php - 读取或写入多个 JSON 对象到单个文件
- unit-testing - 如何在我的 XUnit 单元测试中使用 Microsoft.Extensions.Configuration.IConiguration
- kotlin - RxJava / RxKotlin - 如果上一步失败,andThen 仍然执行。如何停止?
- angular - BehaviorSubject 被多次执行
- ios - 什么是 Secure Enclave ECIES 加密数据格式?