问题描述
我试图绘制一系列(长度n)的元组(低,高)作为垂直线(长度=高-低)的绘图区域,必须是3 n像素宽。每条垂直线必须只有1个像素的宽度,并且线之间的间距必须正好是2个像素。然而,垂直线不是等间距的。
到目前为止,我能做的是:
- 根据我的系统的dpi(documentation),使用所需的像素宽度和高度绘图
- 以相同的像素尺寸保存图形
- 在给定的x位置上绘制宽度为1 px的垂直线
问题出现在最后一点。线之间的间距不总是2像素,可能是因为定义的绘图大小定义了整个图形的大小,而不仅仅是主绘图区域的大小。
我已经试过以下文章:
- Draw evenly spaced lines in python:对我不起作用,因为x_pos不是用x轴上的pixel_id表示的。
示例
给定7个元组(n=7)的序列,每个元组具有(低,高)的形式,我想绘制21(3 n)像素宽的图。因此,该图应包含7条垂直线,每条垂直线在y轴上从低值延伸到高值。在最终图中应排除轴。线的x位置应该在像素2、5、8、11、14、17和20处。
问题是,matplotlib似乎没有保留定义的间距,可能是由于图周围隐式添加的边界(见下图)。
最后的代码生成了这个图(缩放的png):
图中显示了需要解决的问题:
- 钢筋间距不一致(即行2和3之间的像素间隔应该是2而不是1)。
- 主绘图区域必须为3 n像素宽,而不是整个图形。
示例代码:
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"Recognized DPI: {SYS_DPI}")
# create example dataset
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)]
width_pixel = len(example_series)*3
height_pixel = 10
# define xlims
y_min_vals = [x[0] for x in example_series]
y_vals_vals = [x[1] for x in example_series]
min_y, max_y = min(y_min_vals), max(y_vals_vals)
# define x positions and xlims
x_pos = np.arange(0, width_pixel, step=3)+2 # 2,5,8,11,14,17,20
min_x, max_x = 0, width_pixel
# create plot of needed size
fix, ax = plt.subplots(
figsize=(width_pixel/SYS_DPI, height_pixel/SYS_DPI), dpi=SYS_DPI)
ax.set_facecolor("white")
ax.set_axis_off()
ax.set_xlim((min_x, max_x))
ax.set_ylim(min_y, max_y)
for idx, val in enumerate(example_series):
print(f"{idx}: values: {val}")
ax.plot([x_pos[idx], x_pos[idx]], [val[0], val[1]],
color="black", linewidth=1)
plt.savefig(plot_path/"test.png",
bbox_inches=None,
pad_inches=0,
transparent=False,
dpi=SYS_DPI,
facecolor="white")
1条答案
按热度按时间fzsnzjdm1#
我通过改变轴的长宽比来获得你想要的图片,并将相对轴的位置设置为(0,0,1,1)。
放大截图我得到的(分辨率21*10像素)