dpi与图形大小的关系

Posted

技术标签:

【中文标题】dpi与图形大小的关系【英文标题】:Relationship between dpi and figure size 【发布时间】:2018-05-17 22:18:12 【问题描述】:

我已经使用 matplotlib 创建了一个图形,但我已经意识到绘图轴和绘制的线被缩小了。

阅读此earlier discussion thread,它解释了如何设置图形大小。

fig, ax = plt.subplots()

fig.set_size_inches(3, 1.5)

plt.savefig(file.jpeg, edgecolor='black', dpi=400, facecolor='black', transparent=True)

使用上面的代码(为简洁起见,删除了其他配置),我确实得到了一个具有1200 X 600 所需尺寸(我们也应该说分辨率?)和所需文件大小的图像文件。

投影图像以不寻常的方式缩小,例如放大注释。虽然我可以在轴上设置标签的大小,但由于底部和右侧的脊椎很大,绘制的线也很大,因此该图看起来与比例不成比例。

因此问题是,哪些配置出了问题?

【问题讨论】:

我不太明白这个问题。但我能说的是,当图形大小以英寸 dpi为单位时,您需要更改您认为“太大”的对象的大小,即设置字体大小,线宽,刻度线等更小。通常,您只需将 dpi 尺寸固定为英寸即可获得所需的数字。 @ImportanceOfBeingErnest 我创建了一张图片,结果是所需尺寸,文件大小在所需范围内。然而,绘制的图表被证明过于放大/缩小。阅读其他线程似乎可能存在缩放和纵横比问题。您声明每个元素大小的建议听起来很不寻常,因为我认为应该有一种方法可以根据先前设置的 figsize() 和 dpi 参数自动调整画布中的所有元素。 让我再试一次:如果例如像素尺寸为1200 X 600,您通常会创建一个尺寸为(12 x 6) 英寸和100 dpi 的图形,在这种情况下,线条的尺寸可能足够大。使用 400 的 dpi 会使图中的每个点变大 4 倍。显然这不是你想要的。但是如果你需要它,你可以按比例缩小元素(例如,用 0.25 而不是 1 制作线条)。 (这里没有缩放或方面的问题,这就是它的工作原理和预期。) 看你提到的评论,这是完全不同的东西;它告诉您,即使您使用方形图形,您也不会得到方形轴。这与你这里的问题完全无关。 我想我明白你的意思。我对 dpi 和 figsize(x,y) 之间关系的理解与您所解释的略有不同。根据您的评论,我已经测试了您的建议,看起来很有希望。也许我应该更改问题的标题... 【参考方案1】:

图形大小 (figsize) 确定图形的大小(以英寸为单位)。这给出了轴(和其他元素)在图形内的空间量。 matplotlib 2 中的默认图形大小为 (6.4, 4.8) 英寸。较大的图形大小将允许显示更长的文本、更多轴或更多刻度标签。

每英寸点数 (dpi) 确定图形包含多少像素。 matplotlib 中的默认 dpi 为 100。figsize=(w,h) 的数字将有

px, py = w*dpi, h*dpi  # pixels
# e.g.
# 6.4 inches * 100 dpi = 640 pixels

所以为了得到一个像素大小为例如(1200,600) 您可以选择图形大小和 dpi 的几种组合,例如

figsize=(15,7.5), dpi= 80
figsize=(12,6)  , dpi=100
figsize=( 8,4)  , dpi=150
figsize=( 6,3)  , dpi=200
etc.

现在,有什么区别?这是由图中元素的大小决定的。大多数元素(如线条、标记、文本)的大小以磅为单位。 Matplotlib 数字使用 每英寸点数 (ppi) 为 72。厚度为 1 点的线将为 1./72。英寸宽。字体大小为 12 磅的文本将为 12./72。英寸高。

当然,如果您更改以英寸为单位的图形大小,点数不会改变,因此以英寸为单位的较大图形仍然具有相同的元素大小。 因此,更改图形大小就像拿一张不同大小的纸一样。这样做当然不会改变用同一支笔绘制的线条的宽度。

另一方面,更改 dpi 会缩放这些元素。在 72 dpi 时,1 磅大小的线是一个像素强。在 144 dpi 时,这条线的强度为 2 个像素。 因此,较大的 dpi 将起到放大镜的作用。所有元素都根据镜头的放大率进行缩放。

下图左侧显示了恒定图形大小和变化 dpi 的比较。在右侧,您会看到恒定的 dpi 和变化的图形大小。每行中的图形具有相同的像素大小。

要重现的代码:

import matplotlib.pyplot as plt
%matplotlib inline

def plot(fs,dpi):
    fig, ax=plt.subplots(figsize=fs, dpi=dpi)
    ax.set_title("Figsize: , dpi: ".format(fs,dpi))
    ax.plot([2,4,1,5], label="Label")
    ax.legend()

figsize=(2,2)
for i in range(1,4):
    plot(figsize, i*72)

dpi=72
for i in [2,4,6]:
    plot((i,i), dpi)

【讨论】:

"Matplotlib 数字使用每英寸点数 (ppi) 为 72" - 你从哪里找到的?我在任何地方都找不到这个。我唯一能找到的是默认 DPI 是 100。 @LoneLearner 是的,transforms tutorial 的文档中只有一个非常隐藏的参考。当然,这一切都在代码中,例如here. @A.Hendry dpi 表示每英寸的点数(像素)。如果将 dpi 加倍,则点数会加倍。一条 1 像素宽的线将是 2 像素宽。假设您有一条宽度为 1 点的线。它将是 1 点 / ppi * dpi = 1 / 72 ppi * 72 dpi = 1 像素。现在你将 dpi 加倍,因此 1 点 / ppi * dpi = 1 / 72 ppi * 144 dpi = 2 像素。 @ImportanceOfBeingErnest 感谢您的解释。那么为什么图形在左边随着 dpi 的增加而变大呢?它们不都应该是 2 英寸 x 2 英寸吗? @ImportanceOfBeingErnest 关于增加 DPI 的任何建议,就像您在此处所做的那样,同时保持文本和行大小大致相同?您可以浏览每项设置,但要更改的设置很多..

以上是关于dpi与图形大小的关系的主要内容,如果未能解决你的问题,请参考以下文章

dpi与图形大小的关系

matplotlib 设置图形大小时 figsize 与 dpi 的关系

Android 屏幕适配屏幕适配基础概念 ③ ( 屏幕像素密度 DPI 与素材大小关联 | 屏幕像素密度 DPI 与 屏幕密度限定符关联 )

Android 屏幕适配屏幕适配基础概念 ③ ( 屏幕像素密度 DPI 与素材大小关联 | 屏幕像素密度 DPI 与 屏幕密度限定符关联 )

如何获取 matplotlib 图形大小

如何更改使用 Matplotlib 绘制的图形的大小?