Matplotlib Colormap未按预期返回对应值颜色,求修复方案
修复Matplotlib中FancyArrowPatch颜色映射不生效的问题
问题出在你调用colormap的方式上:cmap(row.value)直接传入了原始的value值(0-15),但Matplotlib的colormap函数只接受0到1之间的归一化数值。当输入值大于1时,会被自动截断为1,所以所有箭头都用了colormap最左端的黄色。
有两种简单的修复方式:
方法一:利用已定义的ScalarMappable做颜色转换
你已经创建了scalarmappable对象,它自带归一化逻辑,直接用它的to_rgba方法就能得到正确的颜色:
# 替换原代码中的color参数 color=scalarmappable.to_rgba(row.value)
方法二:手动归一化数值
如果不想依赖ScalarMappable,也可以自己计算归一化后的值:
# 先计算0-1之间的归一化值 norm_value = (row.value - vmin) / (vmax - vmin) # 再传入colormap color=cmap(norm_value)
修改后的完整代码(方法一)
%matplotlib inline import matplotlib.pyplot as plt import matplotlib.patches as patches from matplotlib import style from matplotlib import colors import pandas as pd import numpy as np style.use('ggplot') plot_df = pd.DataFrame({ 'from': [[0, 0], [10, 10], [15, 15], [20, 20]], 'to':[[10, 10], [20, 20], [30, 30], [40, 40]], 'value':[0, 5, 10, 15] }) plot_df['connectionstyle'] = 'arc3, rad=.55' plot_df['arrowstyle'] = 'Simple, tail_width=1, head_width=10, head_length=15' fig, ax = plt.subplots() vmin = 0 vmax = 15 scalarmappable = plt.cm.ScalarMappable(norm=colors.Normalize(vmin=vmin, vmax=vmax), cmap='YlOrRd') cmap = scalarmappable.get_cmap() cbar = fig.colorbar(scalarmappable, ax=ax) ticks = np.linspace(vmin, vmax, 5) cbar.ax.set_yticks(ticks) cbar.ax.set_yticklabels([f'{tick:.0f}' for tick in ticks]) cbar.outline.set_linewidth(0) for _, row in plot_df.iterrows(): start_x = row['from'][0] start_y = row['from'][1] dest_x = row['to'][0] dest_y = row['to'][1] plt.scatter([start_x, dest_x], [start_y, dest_y], color='k') p = patches.FancyArrowPatch( (start_x, start_y), (dest_x, dest_y), connectionstyle=row.connectionstyle, arrowstyle=row.arrowstyle, color=scalarmappable.to_rgba(row.value) # 这里是修改的地方 ) ax.add_patch(p) fig.tight_layout()
这样修改后,箭头就会根据value值从黄色过渡到红色,和颜色条的对应关系一致。
内容的提问来源于stack exchange,提问作者Zeno Dalla Valle
相关产品推荐
相关产品推荐

