如何让叠加的散点图与matshow矩阵图尺寸同步缩放
实现散点标记与matshow格子尺寸同步适配的方法
问题原因
你目前使用的scatter函数的s参数为绝对面积单位(磅的平方),不会随矩阵维度变化、画布缩放自动匹配数据坐标下的格子尺寸,因此矩阵维度调整后会出现标记超出格子的问题。
推荐解决方案:使用数据坐标定义的Patch绘制标记
该方案无需反复调整参数,天生适配任意矩阵维度、任意缩放比例,标记尺寸始终和格子保持固定比例:
示例代码
import matplotlib.pyplot as plt import numpy as np from matplotlib.patches import RegularPolygon # 5行20列的矩阵场景 ax = plt.axes() mat = np.random.random((5, 20)) ax.matshow(mat, aspect='equal') # 在坐标(1,2)处绘制向下的三角形,外接圆半径设为0.5即可刚好填满单个格子 # orientation参数设为np.pi对应三角形向下,和scatter的marker='v'效果完全一致 tri = RegularPolygon( xy=(1, 2), numVertices=3, radius=0.5, orientation=np.pi, facecolor="C0", edgecolor="none" ) ax.add_patch(tri) plt.show()
多标记场景
如果需要批量绘制多个标记,循环添加Patch即可:
# 示例:在多个位置绘制三角形 points = [(1,2), (3,4), (0,1)] for x, y in points: tri = RegularPolygon(xy=(x,y), numVertices=3, radius=0.5, orientation=np.pi, facecolor="C0") ax.add_patch(tri)
备选方案:动态计算scatter的s参数
如果一定要使用scatter函数绘制,可以在matshow渲染完成后,基于当前轴的坐标变换动态计算s的取值:
import matplotlib.pyplot as plt import numpy as np def calc_adaptive_s(ax, fill_ratio=1.0): # 将数据坐标下1单位长度转换为显示像素长度 p0 = ax.transData.transform((0, 0)) p1 = ax.transData.transform((1, 0)) pixel_per_unit = abs(p1[0] - p0[0]) # 调整系数根据marker形状校准,v形marker校准为1350时刚好填满格子 adjust_coef = 1350 * fill_ratio return (pixel_per_unit ** 2) * adjust_coef # 调用示例 ax = plt.axes() mat = np.random.random((5, 20)) ax.matshow(mat, aspect='equal') # 必须在matshow绘制完成、轴范围确定后计算s s = calc_adaptive_s(ax) ax.scatter([1], [2], marker='v', s=s) plt.show()
注意:该方案仅适用于绘制后不修改轴范围、不缩放的场景,如果后续手动调整画布需要重新计算
s值。
内容的提问来源于stack exchange,提问作者InertialObserver
相关产品推荐
相关产品推荐

