如何在指定像素位置绘制等间距竖线?Matplotlib间距异常问题
解决Matplotlib绘图区域尺寸不符导致竖线间距错误的问题
问题核心
需要在3n像素宽的绘图区域内,绘制n条1像素宽的竖线,要求线与线之间的间距严格为2像素(例如n=7时,绘图区域宽21像素,竖线应位于像素位置2、5、8、11、14、17、20)。当前实现通过设置Figure尺寸来控制像素大小,但实际竖线间距不符合预期,原因是Figure尺寸包含了默认边距等额外空间,真正的绘图区域(Axes)并非目标的3n像素宽。
解决方案
要让Axes(主绘图区域)的像素尺寸完全匹配目标值,需手动让Axes占满整个Figure,消除所有默认边距,并确保坐标系统与像素位置一一对应。
修改后的代码
from pathlib import Path import matplotlib.pyplot as plt from ctypes import windll import numpy as np plot_path = Path("./plots/testing/") plot_path.mkdir(parents=True, exist_ok=True) SYS_DPI = windll.user32.GetDpiForSystem() print(f"识别到的系统DPI: {SYS_DPI}") # 示例数据集 example_series = [(1.3, 4.2), (5.3, 8.9), (4.0, 5.5), (6, 7.8), (3.2, 4.5), (5.1, 8.1), (3, 8)] n = len(example_series) width_pixel = n * 3 height_pixel = 10 # 计算y轴范围 min_y = min(val[0] for val in example_series) max_y = max(val[1] for val in example_series) # 计算竖线的x像素位置(严格对应目标像素点) x_pos = np.arange(2, width_pixel, step=3) # 2,5,8,11,14,17,20 # 创建画布并让Axes完全占满画布,消除所有边距 fig = plt.figure(figsize=(width_pixel/SYS_DPI, height_pixel/SYS_DPI), dpi=SYS_DPI) ax = fig.add_axes([0, 0, 1, 1]) # [左, 底, 宽, 高] 均为0-1范围,占满整个画布 # 配置绘图样式 ax.set_facecolor("white") ax.set_axis_off() ax.set_xlim(0, width_pixel) # x轴范围严格对应画布像素宽度 ax.set_ylim(min_y, max_y) # 绘制竖线:确保线宽为1像素,端点无扩展 for idx, val in enumerate(example_series): ax.plot([x_pos[idx], x_pos[idx]], [val[0], val[1]], color="black", linewidth=1, solid_capstyle='butt') # 保存图像:无额外边距,严格按目标像素尺寸保存 plt.savefig(plot_path/"test_fixed.png", bbox_inches=None, pad_inches=0, transparent=False, dpi=SYS_DPI, facecolor="white") plt.close()
关键改动说明
- Axes完全占满画布:使用
fig.add_axes([0,0,1,1])替代subplots(),让绘图区域完全覆盖整个Figure,彻底消除默认的边距和布局间隙,保证Axes的像素尺寸与Figure完全一致。 - 严格的坐标映射:x轴范围设置为
(0, width_pixel),此时x坐标值直接对应图像的像素位置(例如x=2就是图像的第3个像素点,索引从0开始)。 - 精确的线条控制:添加
solid_capstyle='butt'参数,避免Matplotlib默认的线条端点扩展(默认是圆形端点,会额外占1像素宽度),确保竖线正好是1像素宽。 - 简化计算:直接用
np.arange(2, width_pixel, step=3)生成目标x位置,逻辑更清晰。
验证效果
修改后生成的图像宽度严格为21像素(n=7时),用图像查看工具放大后可看到竖线准确位于像素位置2、5、8等,线与线之间的间距正好是2像素,完全符合需求。
内容的提问来源于stack exchange,提问作者Lars
相关产品推荐
相关产品推荐

