2017-10-26 5 views
1

1つの図に2つの棒グラフのサブプロットがあります。私は棒グラフの総面積が2つのサブプロット間でどのように比較されているか知りたい。私はax.bar()が矩形オブジェクトのコレクションを返すことを知っている、と私は次のようにその面積を計算しようとしました:matplotlibグラフの四角形の「実数」領域を見つけるにはどうすればよいですか?

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

トリックは、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 

(マイナー落とし穴はの注意すべき:このREPRO例では問題ではない、時にはマイナス幅または高さを与えることができbbox.size、私は横にそれを観察しました。バーが右から左に向かう棒グラフ。安全のため絶対値を取る方が良い。)

関連する問題