🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

6794閲覧

matplotlibでaxisの外側に線などを描画したい

sagittarius

総合スコア5

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/09/07 02:09

棒グラフの外側に中括弧みたいなものや線を描いて注釈のようなものを表示したいです。
棒グラフのコードはこんな感じです。

python

1import numpy as np 2import matplotlib 3import matplotlib.colors as colors 4import matplotlib.pyplot as plt 5from matplotlib import lines 6 7def main(): 8 x = np.arange(8) 9 10 data = np.array([[3.8, 3.2, 3.5, 3.2, 3.8, 4.0, 4.1, 3.4], 11 [3.1, 3.0, 3.4, 3.8, 3.3, 4.2, 4.0, 3.2], 12 [3.2, 3.5, 3.4, 2.2, 3.1, 4.2, 4.4, 3.4] 13 ]) 14 15 data_std = np.array([[0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2], 16 [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2], 17 [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]]) 18 19 x_lables = ["XXXXXX", "XXX", "XXXXXXX", "XXXXXX", "XXX\nXXXXXXXXX", "dfsfit", "asgadgsmentd", "sdagiu"] 20 21 fig, ax = plt.subplots(figsize=(21, 10), dpi=210) 22 bar_width = 0.2 23 24 ax.bar(x, data[0], bar_width, color=colors.cnames['hotpink'], label='AAA', capsize=6, yerr=data_std[0]) 25 ax.bar(x + bar_width, data[1], bar_width, color=colors.cnames['deepskyblue'], label='BBB', capsize=6, yerr=data_std[1]) 26 ax.bar(x + 2*bar_width, data[2], bar_width, color=colors.cnames['cornflowerblue'], label='CCC', capsize=6, yerr=data_std[2]) 27 28 ax.set_ylabel('XXXXXXX', weight='bold', fontsize=36) 29 ax.set_ylim([1,5]) 30 ax.set_yticks([1,2,3,4,5]) 31 ax.tick_params(axis="y", labelsize=36) 32 ax.set_xticks(x + bar_width) 33 ax.set_xticklabels(x_lables, weight='bold', fontsize=36, rotation=45) 34 ax.legend(loc="best", fontsize=36, ncol=3) 35 36 plt.grid(True, 'major', 'y', ls='--', lw=.5, c='k', alpha=.3) 37 plt.tick_params(bottom=False) 38 39 plt.savefig('sample.eps', bbox_inches='tight', pad_inches=0.2) 40 plt.show() 41 42if __name__ == '__main__': 43 main()

これに注釈のようなものを下の方にaxisの外側に付け加えたいです。外側にテキストを表示するのはfig.textでできるのは確認したのですが、線などはどうすればよいのかわかりません。

理想となる結果はこんな感じです。
イメージ説明

中括弧みたいなやつではなく線でもいいです。
イメージ説明

理想画像は他のソフトで加工しているので劣化したりしてしまいます。matplotlib(もしくはほかのpythonライブラリでもいいので)で完結してepsファイルとして出力するのが望ましいです。

スタックオーバーフローで解決策のようなものがあったのですが、
https://stackoverflow.com/questions/5021663/how-to-draw-a-line-outside-of-an-axis-in-matplotlib-in-figure-coordinates

追加のaxisの要素を消したりする必要がありそうなので、あまりやりたくありません。
matplotlibにとって領域外の要件でなければ、スマートな方法がないかとお聞きしたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

図のような注釈を作成できるような関数はありませんが、Axes.plot で線を引き、Axes.text でテキストを描画することで以下のように作成できます。

コード

python

1import numpy as np 2import matplotlib 3import matplotlib.colors as colors 4import matplotlib.pyplot as plt 5from matplotlib import lines 6 7 8x = np.arange(8) 9 10data = np.array( 11 [ 12 [3.8, 3.2, 3.5, 3.2, 3.8, 4.0, 4.1, 3.4], 13 [3.1, 3.0, 3.4, 3.8, 3.3, 4.2, 4.0, 3.2], 14 [3.2, 3.5, 3.4, 2.2, 3.1, 4.2, 4.4, 3.4], 15 ] 16) 17 18data_std = np.array( 19 [ 20 [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2], 21 [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2], 22 [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2], 23 ] 24) 25 26x_lables = [ 27 "XXXXXX", 28 "XXX", 29 "XXXXXXX", 30 "XXXXXX", 31 "XXX\nXXXXXXXXX", 32 "dfsfit", 33 "asgadgsmentd", 34 "sdagiu", 35] 36 37fig, ax = plt.subplots(figsize=(21, 10), dpi=210) 38bar_width = 0.2 39 40ax.bar( 41 x, 42 data[0], 43 bar_width, 44 color=colors.cnames["hotpink"], 45 label="AAA", 46 capsize=6, 47 yerr=data_std[0], 48) 49ax.bar( 50 x + bar_width, 51 data[1], 52 bar_width, 53 color=colors.cnames["deepskyblue"], 54 label="BBB", 55 capsize=6, 56 yerr=data_std[1], 57) 58ax.bar( 59 x + 2 * bar_width, 60 data[2], 61 bar_width, 62 color=colors.cnames["cornflowerblue"], 63 label="CCC", 64 capsize=6, 65 yerr=data_std[2], 66) 67 68ax.set_ylabel("XXXXXXX", weight="bold", fontsize=36) 69ax.set_ylim([1, 5]) 70ax.set_yticks([1, 2, 3, 4, 5]) 71ax.tick_params(axis="y", labelsize=36) 72ax.set_xticks(x + bar_width) 73ax.set_xticklabels(x_lables, weight="bold", fontsize=36, rotation=45) 74ax.legend(loc="best", fontsize=36, ncol=3) 75 76plt.grid(True, "major", "y", ls="--", lw=0.5, c="k", alpha=0.3) 77plt.tick_params(bottom=False) 78 79### 追加のコード begin 80 81 82def add_anotation(ax, x1, x2, label): 83 y1 = -0.7 84 y2 = -1.0 85 86 # 線を引く 87 xs = [x1, x1, x2, x2] 88 ys = [y1, y2, y2, y1] 89 ax.plot(xs, ys, "k", clip_on=False) 90 91 # テキストをつける。 92 center = (x1 + x2) / 2 93 ax.text(center, y2 - 0.1, label, fontsize=36, ha="center", va="top") 94 95 96xticks = ax.get_xticks() 97add_anotation(ax, xticks[0], xticks[4], "label1") 98add_anotation(ax, xticks[5], xticks[7], "label2") 99 100### 追加のコード end 101 102plt.show()

イメージ説明

投稿2019/09/09 05:57

tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sagittarius

2019/09/09 07:41

ありがとうございます. 丁寧なコードまで載せてくださって,大変わかりやすかったです.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問