如何控制Matplotlib绘图中箭头标记的点间距与行间距?
调整Matplotlib箭头标记的水平与垂直间距
你当前的需求是消除箭头间的水平空隙、减小行间距,同时保留x轴显示箭头数量的特性。问题出在Matplotlib默认的自动坐标轴缩放会给元素周围预留空白,仅调整figsize无法解决,我们需要通过手动控制坐标轴范围和布局来实现紧密排列。
以下是具体的解决方案和修改后的代码:
核心修改点
- 使用
matplotlib.axes.Axes对象替代全局plt调用,获得更精细的布局控制 - 手动设置x/y轴的显示范围,让箭头标记紧密贴合
- 调整子图边距,去除多余空白
- 可选:调整y轴刻度的间距进一步压缩行空间
修改后的完整代码
import numpy as np import matplotlib.pyplot as plt import matplotlib.cm as cm def arrowplot(path, max_LU=0, names=""): if isinstance(path[0], int): # There is only one sequence in "subpaths" path = [path] # get discrete colormap colors_rainbow = cm.hsv(np.linspace(0, 1, max_LU)) # Find the row that has the most amount of triangles. longest_path = max([len(x) for x in path]) num_paths = len(path) # 使用子图对象进行精细控制 fig, ax = plt.subplots(figsize=(longest_path, num_paths*1)) # 调整figsize的垂直比例 for i in range(num_paths): for j in range(len(path[i])): colour = colors_rainbow[abs(path[i][j]) - 1] if path[i][j] >= 0: ax.scatter(j, i, color=colour, marker=">", s=100, edgecolor="black") else: ax.scatter(j, i, color=colour, marker="<", s=100, edgecolor="black") # 设置坐标轴范围,消除空隙:每个点(j,i)位于网格中心,范围从-0.5到对应最大值-0.5 ax.set_xlim(-0.5, longest_path - 0.5) ax.set_ylim(-0.5, num_paths - 0.5) # 设置y轴刻度 if names == "": names = range(num_paths) ax.set_yticks(ticks=range(num_paths), labels=names) # 保留x轴显示箭头数量的特性,设置x轴刻度为0到longest_path-1 ax.set_xticks(ticks=range(longest_path)) # 调整子图边距,去除多余空白 plt.tight_layout() plt.savefig("arrowplot.png", format="png", dpi=200, bbox_inches='tight') plt.show() plt.close() return None # 示例测试 A = [1,2,3,9,4,5] B = [2,3,5,-1,7,4,5] arrowplot([A,B], names=["A", "B"], max_LU=9) # 另一个示例 ref = list(range(1, 45, 1)) A2 = [1, 2, 3, 4, 5, 6, 7, -13, -12, -1, -44, -43, -42, -41, -40, 39, -38, -37, -36, 8, 9, 11, 14, 15, 16, 17, 19, 20, 21, -37, -36, 19, 20, 14, 15, 16, -24, -23, -22, 17, 18, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -17, -16, -15, -14, -11, -10, -9, -8, 36, 37, 38, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, -18, -17, 22, 23, 24, -16, -15, -14, -20, -19, 36, 37, 38, -39, 40, 41, 42, 43, 44] B2 = [1, 2, 3, 4, 5, 6, 7, -13, -12, -1, -44, -43, -42, -41, -40, 39, -38, -37, -36, 8, 9, 11, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -18, -17, 22, 23, 24, -16, -15, -14, -20, -19, 36, 37, -21, -20, -19, -17, -38, -37, -36, 8, 9, 10, 11, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, -18, -17, 22, 23, 24, -16, -15, -14, -20, -19, 36, 37, 38, -39, 40, 41, 42, 43, 44] names = ["A", "B", "C"] arrowplot([ref, A2, B2], max_LU=44, names=names)
关键修改解释
- 坐标轴范围设置:
ax.set_xlim(-0.5, longest_path - 0.5)和ax.set_ylim(-0.5, num_paths - 0.5)让每个箭头标记刚好填满对应的网格单元,消除了水平和垂直方向的空隙。 - 子图边距调整:
plt.tight_layout()和bbox_inches='tight'确保保存图片时没有多余的空白区域。 - figsize垂直比例调整:把
len(path)*1.5改为num_paths*1,进一步压缩垂直方向的布局空间,你可以根据需要微调这个系数。 - 保留x轴计数特性:
ax.set_xticks(ticks=range(longest_path))确保x轴显示所有箭头的位置序号,符合你的需求。
内容的提问来源于stack exchange,提问作者Marco Monti
相关产品推荐
相关产品推荐

