图例目前是使用以下方式创建的:
plt.gca().legend(loc="upper right")
我该如何将图例更改为类似于色条的形式?另外,色条应放置在绘图底部。 编辑: 上传了代码和数据以便重现,链接如下: https://www.dropbox.com/sh/8xgyxybev3441go/AACKDiNFBqpsP1ZttsZLqIC4a?dl=0
plt.gca().legend(loc="upper right")
旁注 - 存在的漏洞
你放在 Dropbox 上的代码“开箱即用”并不起作用。特别是,你试图在两个地方将 datetime.timedelta
除以 numpy.timedelta64
,结果失败了。
你自己进行了标准化和颜色映射(根据你的标准化值的 int()
转换调用到 color_list
)。你从中减去了 1
,但实际上不需要这样做——你已经使用 int()
对值进行了向下取整。这样做的结果是,你可能会得到一个索引为 -1
的值,这意味着你的非常小的值被错误地映射到最大值的颜色上。如果绘制列 'BIOM'
,这一点最为明显。
我通过给你要除以的值的总范围添加了一个微小的值 (0.00001
) 来解决这个问题。这是一个 hack,我不确定这种映射方法是否是 matplotlib 的最佳使用方式,但这是完全不同的问题。
随着这些错误的修复,并在所有现有subplot下方添加一个最后的suplot(即在对subplot2grid()的所有调用中将3替换为4),您可以执行以下操作:
替换您的
plt.gca().legend(loc="upper right")
使用
# plot an overall colorbar type legend
# Grab the new axes object to plot the colorbar on
ax_colorbar = plt.subplot2grid((4,num_yrs), (3,0),rowspan=1,colspan=num_yrs)
mappableObject = matplotlib.cm.ScalarMappable(cmap = palettable.colorbrewer.sequential.BuPu_9.mpl_colormap)
mappableObject.set_array(numpy.array(df[col_name]))
col_bar = fig.colorbar(mappableObject, cax = ax_colorbar, orientation = 'horizontal', boundaries = numpy.arange(min_val,max_val,(max_val-min_val)/10))
# You can change the boundaries kwarg to either make the scale look less boxy (increase 10)
# or to get different values on the tick marks, or even omit it altogether to let
col_bar.set_label(col_name)
ax_colorbar.set_title(col_name + ' color mapping')
我使用了你的两列数据('NMN'
和'BIOM'
),并在Python 2.7上进行了测试(考虑到print
语句的语法,我假设你正在使用Python 2.x)。
最终的代码可以直接与你的数据文件一起使用,在此处的gist中。
它创建了一个ScalarMappable
对象,供matplotlib用于将值映射到颜色上。它将数组设置为基于您正在处理的列中的所有值。然后使用Figure.colorbar()
添加颜色条 - 传递可映射对象以使标签正确。我添加了边界,以便明确显示最小值 - 如果您希望matplotlib自行解决,则可以省略该部分。
P.S. 我将色图设置为palettable.colorbrewer.sequential.BuPu_9.mpl_colormap
,与您的get_colors()
函数匹配,该函数获取这些颜色作为9个成员列表。我强烈建议导入要使用的色图作为一个好名字,以使mpl_colors和mpl_colormap的使用更易于理解,例如:
import palettable.colorbrewer.sequential.BuPu_9 as color_scale
color_scale.mpl_colormap
这样,你就可以保持你的代码DRY,并且只需更改一次颜色即可。
对于审美理念来说,颜色条可能有点大(当然高)。 有几种可能的选项。 我将指出两个:
“正确”的方法可能是使用 Gridspec
。
您可以使用现有的方法,但增加行数,使颜色条仍在一行中,而其他元素跨度比当前跨度更多的行。
tight_layout
和w_pad=0.0
以避免标签冲突。您可以调整此设置以获得所需的精确尺寸。新代码在这里。 :
myColorbar = matplotlib.colorbar.ColorbarBase(myAxes, cmap=myColorMap,
norm=myNorm,
orientation='vertical')