我在将颜色栏添加到Matplotlib中的线图网格时遇到了麻烦。
我有一个图表网格,每个图表显示64行。这些线描述了在特定超参数h
的64个不同值下优化同一系统时的惩罚值与时间的关系。
由于线条太多而不是使用标准图例,我想使用颜色条,并使用h
的值为线条着色。换句话说,我喜欢看起来像这样的东西:
上面是通过添加一个新轴来保持颜色条,通过调用figure.add_axes([0.95, 0.2, 0.02, 0.6])
,将轴位置明确地作为参数传递给该方法来完成的。然后通过实例化ColorbarBase()
,在示例代码here中创建颜色条。对于单个情节来说这很好,但是我想制作一个像上面那样的情节网格。
为此,我尝试将子图的数量加倍,并使用每个其他子图的轴作为颜色条。不幸的是,这导致色条具有与图形相同的尺寸/形状:
有没有办法缩小像上面的1x2网格的子图网格中的colorbar子图?
理想情况下,如果颜色条与其描述的线图共享相同的轴,则效果会非常好。我看到colorbar.colorbar()函数有一个ax参数:
斧
父轴对象,新颜色条轴的空间将被盗取。
这听起来不错,除了colorbar.colorbar()
要求你传递一个imshow图像或ContourSet
,但我的情节既不是图像也不是等高线图。我可以使用ColorbarBase
实现相同(轴共享)效果吗?
答案 0 :(得分:0)
事实证明,只要给定行中的所有绘图具有相同的高度,并且给定列中的所有绘图具有相同的宽度,就可以有不同形状的子绘图。
您可以使用gridspec.GridSpec执行此操作,如this answer中所述。
因此,我将带有线图的列设置为比带有颜色条的列宽20倍。代码如下:
grid_spec = gridspec.GridSpec(num_rows,
num_columns * 2,
width_ratios=[20, 1] * num_columns)
colormap_type = cm.cool
for (x_vec_list,
y_vec_list,
color_hyperparam_vec,
plot_index) in izip(x_vec_lists,
y_vec_lists,
color_hyperparam_vecs,
range(len(x_vecs))):
line_axis = plt.subplot(grid_spec[grid_index * 2])
colorbar_axis = plt.subplot(grid_spec[grid_index * 2 + 1])
colormap_normalizer = mpl.colors.Normalize(vmin=color_hyperparam_vec.min(),
vmax=color_hyperparam_vec.max())
scalar_to_color_map = mpl.cm.ScalarMappable(norm=colormap_normalizer,
cmap=colormap_type)
colorbar.ColorbarBase(colorbar_axis,
cmap=colormap_type,
norm=colormap_normalizer)
for (line_index,
x_vec,
y_vec) in zip(range(len(x_vec_list)),
x_vec_list,
y_vec_list):
hyperparam = color_hyperparam_vec[line_index]
line_color = scalar_to_color_map.to_rgba(hyperparam)
line_axis.plot(x_vec, y_vec, color=line_color, alpha=0.5)
对于num_rows=1
和num_columns=1
,这看起来像是: