Matplotlib多热力图子图绘制指定两点间红色粗直线箭头方法
实现思路
你当前使用imshow绘制热力图时,默认使用网格像素坐标系(x轴对应列索引j、y轴对应行索引i,原点在左上角),和你标注矩形、文字用的坐标系完全一致,不需要额外做坐标转换。只需要在遍历子图的循环内,给每个轴对象添加箭头图元即可。
需要注意两个细节:
- 你原有代码中
ax.text(actual_2d[62, 62], actual_2d[62, 62]-10, ...)这行是错误的,把热力图的数值当成了坐标值,会导致文字位置完全错位,直接删除即可 - 箭头的位移参数需要按「终点坐标-起点坐标」计算:起点(62,62)、终点(58,94),对应横向位移dx=58-62=-4,纵向位移dy=94-62=32
修改后完整代码
from matplotlib.patches import Rectangle import numpy as np import matplotlib.pyplot as plt import matplotlib.cm as cm from mpl_toolkits import axes_grid1 import matplotlib.colors as mcolors # 模拟测试数据,实际使用时替换为你的真实data即可 data = np.random.randn(10*150*150) v = np.linspace(-1,1,9) # 补全原有代码缺失的色条刻度变量 fig, axes = plt.subplots(2, 5, figsize=(16, 8)) for i,ax in enumerate(axes.flat): # 修正原有代码缩进问题 sub_plot_data = data[(i)*(150*150):(i+1)*150*150] x = 150 y = 150 pmin = min(sub_plot_data) pmax = max(sub_plot_data) # 配置离散色带 bounds = np.linspace(-1, 1, 10) Discrete_colors = plt.get_cmap('jet')(np.linspace(0,1,len(bounds)+1)) cmap = mcolors.ListedColormap(Discrete_colors[1:-1]) actual_2d = np.reshape(sub_plot_data,(y,x)) im = ax.imshow(actual_2d, interpolation=None, cmap=cmap, vmin=pmin, vmax=pmax) ax.set_title("Sale_Stores-%s - L: %s"%(i+1, 1), fontsize=14, pad=30, x=0.5, y=0.999) ax.set_aspect('auto') # 原有红色起点标记块 ax.add_patch(Rectangle((60, 60), 6, 6, edgecolor='red', facecolor='red', fill=True, lw=2)) ax.text(62, 62, '%s' % 'Sale_1', ha='center', va='center', color='black', fontsize=14) # ========== 新增:红色粗直线箭头 ========== # 参数说明:起点x,起点y,横向位移,纵向位移,宽度设为2实现粗线效果,调整头部宽长让箭头更明显 ax.arrow( 62, 62, -4, 32, color='red', width=2, head_width=6, head_length=4, length_includes_head=True # 让箭头总长度包含头部尺寸,终点位置精准对齐(58,94) ) fig.tight_layout(h_pad=10) plt.subplots_adjust(left=0.02, bottom=0.1, right=0.91, top=0.8, wspace=0.1, hspace=0.5) cbaxes = fig.add_axes([0.94, 0.05, 0.02, 0.8]) cbar = fig.colorbar(im, ax=axes.flat, ticks=v, extend='both', cax=cbaxes) cbar.ax.tick_params(labelsize=10) cbar.ax.set_yticklabels([str(i) for i in v], fontsize=12) # 隐藏所有子图坐标轴刻度 for ax in axes.flat: ax.tick_params(left=False, labelleft=False, top=False, labeltop=False, right=False, labelright=False, bottom=False, labelbottom=False) plt.show()
参数调整说明
- 如果觉得箭头不够粗,可以把
width参数调大(比如改成3) - 如果箭头头部大小不合适,对应调整
head_width、head_length即可 - 如果后续你启用了
extent参数绑定地理坐标,只需要把起止点换成对应地理坐标系下的坐标值,箭头用法不变
内容的提问来源于stack exchange,提问作者bluered_earth
相关产品推荐
相关产品推荐

