【问题标题】:How to display python plots at real resolution on screen如何在屏幕上以真实分辨率显示 python 图
【发布时间】:2022-02-05 02:47:17
【问题描述】:

我可以控制 dpi,轴的缩放也很好,我只需要在我使用的任何数字屏幕上可靠地显示绘图像素的方法。

在数字屏幕上显示它们已被证明是棘手的。我已经考虑了屏幕的 dpi 并在生成情节时考虑了这一点。我发现显示绘图的最可靠方法是将它们保存为 .png 文件并在 MS Paint 中打开它们。我最初使用 matplotlib 的标准绘图查看器取得了成功,但是,由于某种原因,即使考虑到 dpi 的变化,我也无法解释在使用 4k 屏幕时它不可靠。我真的很喜欢使用标准查看器,因为它很简单,如果你愿意,你甚至可以探测图像,但是不可靠的缩放对我来说会扼杀这个选项。我做了一些研究,是否有参数可以锁定窗口的缩放功能并将其保持在原始分辨率,但没有发现。

我尝试了其他一些库,例如 PIL 来显示图像,但它使用 OS 图像查看器以最方便的尺寸显示它。

我脑海中浮现的一些想法是:

  • 游戏。我已经修改了那个库,它提供了一些很好的像素控制功能。
  • matplotlib 中内置的替代显示函数,我根本不知道。

这是我正在使用的当前脚本。

import matplotlib.pyplot as plt
import numpy as np
#from PIL import Image
#import matplotlib.image as mpimg

def set_size(w,h, ax= None):
    """w, h: width, height in inches"""
    if not ax: ax=plt.gca()
    l = ax.figure.subplotpars.left
    r = ax.figure.subplotpars.right
    t = ax.figure.subplotpars.top
    b = ax.figure.subplotpars.bottom
    print(l,b,r,t)
    figw = float(w)/(r-l)
    figh = float(h)/(t-b)
    ax.figure.set_size_inches(figw, figh)
    
#Establishing axis limits
xlabel = "Distance (IN)"
xmin=1800
xmax = 3100 #+ 20 * 100
xstep = 100
xscale = np.arange(xmin, xmax + xstep, xstep)

ylabel = "Velcocity (M/S)"
ymin=0
ymax = 1.0 #+.1 *20
ystep = .1
yscale = np.arange(ymin, ymax + ystep, ystep)
   
#fig, ax=plt.subplots(dpi = 102.4)#For 22in @ 1080p
fig, ax=plt.subplots(dpi = 163)#For 27in @ 4k
#Without removing the margins the scale is off. 
#If the margins could be measured and accounted for then there would be 
#little they could have a value.
plt.subplots_adjust(.04,.05,.96,.95)
plt.margins(x = 0, y = 0) 


#Having issues with the graph scaling
#fig.tight_layout()

ax.set_xticks(xscale)
ax.set_yticks(yscale)

ax.set_xlim(xscale[0], xscale[-1])
ax.set_ylim(yscale[0], yscale[-1])

#ax.plot([0,1,2,3,4,5],[0,1,2,3,4,5])
ax.plot([1900,2100,2400,2700],[.1,.2,.3,.4])

plt.xlabel(xlabel)
plt.ylabel(ylabel)

plt.grid()

set_size(len(xscale)-1, len(yscale)-1)

fig.savefig('plot.pdf')#, bbox_inches = 'tight')
fig.savefig('plot.png')#, bbox_inches = 'tight')
plt.show()

#im = Image.open('axis_ticks_cm.png')
#im.show()

# im = mpimg.imread('axis_ticks_cm.png')
# imgplot = plt.imshow(im)
# plt.show()

我还不知道如何处理图形和轴对象。因此,代码可能看起来像是随意组装的——确实如此。很多尝试和错误,但我正在弄清楚。

轴缩放参考: Axes class - set explicitly size How do you change the size of figures drawn with Matplotlib?

【问题讨论】:

  • 你需要知道图形dpi和屏幕的dpi_ratio。许多 hiDPI 屏幕将比率设置为 2,但用户通常可以在其显示设置中进行调整。
  • @JodyKlymak 感谢您提出这个问题。它把我推向了正确的方向,是的,4k 显示器就是这种情况。我能够进入 Windows 显示设置并对其进行测试。

标签: python numpy matplotlib plot pixel


【解决方案1】:

我找到了适合我的解决方案。正如我的问题的 cmets 中提到的,Windows 缩放因子在 a gui 的大小中起作用,而与 dpi 无关。考虑到这一点,将 dpi 乘以 100/150 以获得 150% 的缩放因子,解决了我在 4k 屏幕上遇到的问题。我确实注意到在 1080p 屏幕上这个比例因子不适用。

标准的 plt.show() 函数似乎工作得很好,只要屏幕上有足够的空间来呈现情节,否则它会按比例缩小。

我确实找到了一种使用 tkinter 库来锁定分辨率的方法。通过简单地获取图像分辨率,然后将 tkinter gui 设置为该大小。然后将图像设置为背景。窗口当然可以被锁定,因此它不能被缩放或拉伸。即使图像大于屏幕,它也不会缩放窗口适合,这正是我需要的。我在下面包含了我的代码。

import tkinter as tk
from PIL import Image

window = tk.Tk()

window.title("Image Viewer")

backPath = 'plot.png'
img = Image.open(backPath)
w, h = img.size

window.resizable(width = False, height = False)
window.geometry(str(w) + 'x' + str(h))

background_image = tk.PhotoImage(file = backPath)
background_label = tk.Label(window, image=background_image)
background_label.place(x=0, y=0)

window.mainloop()

【讨论】:

    猜你喜欢
    • 2021-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多