matplotlib中的矩形位置不正确 [英] Incorrect rectangle location in matplotlib

查看:110
本文介绍了matplotlib中的矩形位置不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作带有条形图的图形,并试图找到它们在图形上的绝对位置(以像素为单位),以便以后进行进一步处理.在我看来,应该可以从关于轴实例的matplotlib的转换信息中找出这一点.具体来说,我正在使用 ax.transData 从数据坐标开始(我知道盒子的位置)以显示坐标.这是一些代码:

I'm making a plot with bars and I'm trying to find their absolute location (in pixels) on the plot for further processing later. It seems to me that this should be able to be figured out from matplotlib's transformation information on the axes instance. Specifically, I'm using ax.transData to go from data coordinates (where I know the box positions) to display coordinates. Here is some code:

import matplotlib.pyplot as plt

x = range(10)
y = range(1, 11)

fig = plt.figure()
ax = fig.add_subplot(111)
bars = ax.bar(x, y, width=.5, label="foo")
ax.monkey_rectangles = bars
ax.legend()

def get_useful_info(fig):
    for ax in fig.get_axes():
        for rect in ax.monkey_rectangles:
            corners = rect.get_bbox().corners()[::3]
            pos = ax.transData.transform(corners)
            left = pos[0,0]
            width = pos[1,0] - pos[0,0]
            bottom = pos[0,1]
            height = pos[1,1] - pos[0,1]
            yield left, width, bottom, height

fig.savefig('foo.png')
for l, w, b, h in get_useful_info(fig):
    print l, w, b, h

这将打印以下内容:

80.0 24.8 48.0 38.4
129.6 24.8 48.0 76.8
179.2 24.8 48.0 115.2
228.8 24.8 48.0 153.6
278.4 24.8 48.0 192.0
328.0 24.8 48.0 230.4
377.6 24.8 48.0 268.8
427.2 24.8 48.0 307.2
476.8 24.8 48.0 345.6
526.4 24.8 48.0 384.0

因此,matplotlib认为我的盒子宽24.8单位(我认为是像素).很好,除了当我实际测量盒子的宽度时,我得到的宽度更像是32像素.这里有什么差异?

So, matplotlib thinks my boxes are 24.8 units (pixels I assume) wide. That's fine except when I actually go to measure the box width, I get something more like 32 pixels wide. What is the discrepancy here?

推荐答案

和往常一样,发布问题时会发生启示……这里的问题是单位不是像素,它们是再点.初始化图形后,将使用默认的每英寸点数进行设置(fig.set_dpi()fig.get_dpi()允许您更改/查询当前图形的分辨率).当然,事情并非如此简单-保存图形时,dpi会根据特定后端的rc设置而变化.对于我来说,默认的后端和png输出为100 dpi.然而,这里不变的一件事是图形尺寸fig.get_size_inches().因此,如果我按比例缩放结果,事情似乎会使我们更加一致……

As usual, the revelation happens when posting the question ... The problem here is that the units are not pixels, they're dots. When the figure is initialized, it is set up with a default dots per inch (fig.set_dpi() and fig.get_dpi() allow you to change/inquire the current figure's resolution). Of course, things can't be that easy -- When you save the figure, the dpi changes based on your rc settings for the particular backend. For me with the default backend and png output, this goes to 100 dpi. One thing which is invariant here, however is the figure size fig.get_size_inches(). So, if I scale my results, things seem to turn our a little more consistently ...

def get_useful_info(fig):
    dpi = fig.get_dpi()
    pngdpi = 100
    scale_x = pngdpi / dpi
    scale_y = pngdpi / dpi
    for ax in fig.get_axes():
        for rect in ax.monkey_rectangles:
            corners = rect.get_bbox().corners()[::3]
            pos = ax.transData.transform(corners)
            left = pos[0,0] * scale_x
            width = (pos[1,0] - pos[0,0]) * scale_x
            bottom = pos[0,1] * scale_y
            height = (pos[1,1] - pos[0,1]) * scale_y
            yield left, width, bottom, height

我有种下沉的感觉,尽管这不是完整的解决方案-毕竟,我们仍在点点滴滴地工作.我不完全确定点如何转换为png图像的像素...我希望显示引擎(在我的特定情况下是Web浏览器)将每个点渲染为单个像素,而不关心图片的报告尺寸.我想只有一些实验才能将其分类出来...

I have a sinking feeling that this isn't the full solution though -- After all, we're still working in dots. I'm not completely sure how a dot translates to a pixel for png images ... My hope is that the display engine (in my particular case, a web browser) renders each dot in a single pixel and doesn't care about the image's reported size. I suppose that only some experimentation will sort that one out ...

这篇关于matplotlib中的矩形位置不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆