如何在matplotlib图表中找到矩形的“真实”区域?

时间:2017-10-26 21:13:08

标签: python matplotlib

我在一张图中有两个条形图子图。我想知道两个子图之间的条形总面积是如何比较的。我知道ax.bar()返回一个Rectangle对象的集合,我试图用以下方式计算它们的区域:

from matplotlib import pyplot as plt
fig, (ax1, ax2) = plt.subplots(1,2)

def get_area(rects):
    area = 0
    for rect in rects:
        area += rect.get_width() * rect.get_height()
    return area

x = range(3)
y1 = [2, 3, 4]
y2 = [20, 30, 30]
r = ax1.bar(x, y1)
print "Total area of bars in first subplot = {:.1f}".format(get_area(r))
r = ax2.bar(x, y2)
print "Total area of bars in 2nd subplot = {:.1f}".format(get_area(r))

打印:

Total area of bars in first subplot = 7.2
Total area of bars in 2nd subplot = 64.0

从实际数字来看,这显然不是我想要捕捉的现实。

two bar chart subplots with different scales

这似乎给了我“数据单元”中的区域,但我真正关心的是它们在屏幕上使用了多少空间。

1 个答案:

答案 0 :(得分:1)

诀窍是使用ax.transData从数据坐标转换为显示坐标。我发现变换上的this tutorial有助于解决这个问题。

from matplotlib import pyplot as plt
import numpy as np

def get_area(ax, rects):
    area = 0
    for rect in rects:
        bbox = rect.get_bbox()
        bbox_display = ax.transData.transform_bbox(bbox)
        # For some reason, bars going right-to-left will have -ve width.
        rect_area = abs(np.product(bbox_display.size))
        area += rect_area
    return area

fig, (ax1, ax2) = plt.subplots(1,2)

x = range(3)
y1 = [2, 3, 4]
y2 = [20, 30, 30]
r = ax1.bar(x, y1)
print "Real area of bars in first subplot = {:.1f}".format(get_area(ax1, r))
r = ax2.bar(x, y2)
print "Real area of bars in 2nd subplot = {:.1f}".format(get_area(ax2, r))

新输出:

Real area of bars in first subplot = 18417.7
Real area of bars in 2nd subplot = 21828.4

(小问题需要注意:bbox.size有时会给出负宽度或高度。这个重复示例中没有问题,但是我在水平条形图上观察到了它从右边到-left。最好采取绝对值来保证安全。)