質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.36%
Matplotlib

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

4865閲覧

Python3のmatplotlibを使ったヒストグラムの作図

yu_2_8_2

総合スコア34

Matplotlib

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2019/06/06 03:58

編集2019/06/06 08:29

Python3のmatplotlibを使いヒストグラムを作成したいのですが、調べてもうまく作成できないので質問致します。

元となる配列は、
__________price sell buy
0 855000.0 0.2275 0.3814
1 855100.0 4.0390 2.0820
2 855200.0 1.7139 0.5200
3 855300.0 3.7723 1.9440
4 855400.0 3.7017 3.9640
5 855500.0 34.5134 5.8022
6 855600.0 17.2817 2.2116
7 855700.0 8.0095 5.2436
8 855800.0 19.0589 3.3583
9 855900.0 5.8494 6.9031

のようなもので、縦軸をpriceで、横軸は、作成するヒストグラムの左半分がsell、右半分がbuyの列を反映させたいです。

以下を出力するのが目標です。(以下の図中のようにバーの色は変えない)
作成したいヒストグラム

どなたか詳しい方いらっしゃいましたらご教授頂きたいです。
よろしくお願いします。

y軸の目盛りが潰れてしまう問題

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

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

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

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

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

guest

回答1

0

ベストアンサー

matplotlib のラッパーライブラリ seaborn の seaborn.barplot を使って、sell と buy の横方向の棒グラフを2つ作成する。
正の値が右方向 → なので、sell の値は符号を反転させることで左方向 ← にする。
そうすることで、人口ピラミッドのような中央が基点となる左右に伸びた棒グラフが作成できる。

python

1from io import StringIO 2 3import pandas as pd 4import seaborn as sns 5 6sns.set(style="whitegrid") 7 8# データフレーム作成 9src = StringIO( 10 """price sell buy 110 855000.0 0.2275 0.3814 121 855100.0 4.0390 2.0820 132 855200.0 1.7139 0.5200 143 855300.0 3.7723 1.9440 154 855400.0 3.7017 3.9640 165 855500.0 34.5134 5.8022 176 855600.0 17.2817 2.2116 187 855700.0 8.0095 5.2436 198 855800.0 19.0589 3.3583 209 855900.0 5.8494 6.9031""" 21) 22data = pd.read_csv(src, delim_whitespace=True) 23 24# 描画する。 25fig, ax = plt.subplots(figsize=(7, 5)) 26 27# 棒グラフのデフォルトは右方向→ 28# sell の値は符号を反転させることで左方向←に棒グラフが作成されるようにする。 29copied = data.copy() # 元のデータを変更しないようにコピーしておく。 30copied["sell"] *= -1 31 32colors = ["#60D394", "#FFD97D"] # 色 33names = ["sell", "buy"] # 列名 34 35for name, color in zip(names, colors): 36 sns.barplot( 37 x=name, 38 y="price", 39 data=copied, 40 color=color, 41 label=name, 42 orient="h", 43 order=copied["price"].iloc[::-1], 44 ax=ax, 45 ) 46 47ax.set_xlabel("") # x 軸のラベル 48ax.set_ylabel("Price", fontsize=12) # y 軸のラベル 49# x 軸の範囲を左右対称になるように調整する。 50max_val = data[["sell", "buy"]].values.max() * 1.1 51ax.set_xlim(-max_val, max_val) 52ax.legend() # 凡例追加 53 54plt.show()

イメージ説明

追記

次の手順でできます。

  1. Axes.get_yticks() で y 軸の目盛りの位置一覧を取り出す。
  2. Axes.get_yticklabels() で y 軸の目盛りのラベル一覧を取り出す。
  3. Axes.set_yticks() で y 軸の目盛りの位置一覧を10個置きにスライスして設定する。
  4. Axes.set_yticklabels() で y 軸の目盛りのラベル一覧を10個置きにスライスして設定する。

python

1from io import StringIO 2 3import pandas as pd 4import matplotlib.pyplot as plt 5import seaborn as sns 6 7sns.set(style="whitegrid") 8 9# データフレーム作成 10num_samples = 100 11data = pd.DataFrame( 12 { 13 "price": np.arange(855000, 855000 + num_samples), 14 "sell": np.random.uniform(0, 10, num_samples), 15 "buy": np.random.uniform(0, 10, num_samples), 16 } 17) 18 19# 描画する。 20fig, ax = plt.subplots(figsize=(7, 5)) 21 22# 棒グラフのデフォルトは右方向→ 23# sell の値は符号を反転させることで左方向←に棒グラフが作成されるようにする。 24copied = data.copy() # 元のデータを変更しないようにコピーしておく。 25copied["sell"] *= -1 26 27colors = ["#60D394", "#FFD97D"] # 色 28names = ["sell", "buy"] # 列名 29 30for name, color in zip(names, colors): 31 sns.barplot( 32 x=name, 33 y="price", 34 data=copied, 35 color=color, 36 label=name, 37 orient="h", 38 order=copied["price"].iloc[::-1], 39 ax=ax, 40 ) 41 42ax.set_xlabel("") # x 軸のラベル 43ax.set_ylabel("Price", fontsize=12) # y 軸のラベル 44# x 軸の範囲を左右対称になるように調整する。 45max_val = data[["sell", "buy"]].values.max() * 1.1 46ax.set_xlim(-max_val, max_val) 47 48# y 軸の目盛りの間隔を10個おきに調整する。 49yticks = ax.get_yticks() 50yticklabels = ax.get_yticklabels() 51ax.set_yticks(yticks[::10]) 52ax.set_yticklabels(yticklabels[::10]) 53 54ax.legend() # 凡例追加 55 56plt.show()

イメージ説明

投稿2019/06/06 05:06

編集2019/06/06 08:59
tiitoi

総合スコア21956

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

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

yu_2_8_2

2019/06/06 05:56

回答ありがとうございます! おかげさまでうまく実装することができました!
yu_2_8_2

2019/06/06 06:20

すいません、y軸を降順にするのはどうすればよいでしょうか? ax.yaxis_inverted() をplt.show()の前に入れても降順になりませんでした・・・
tiitoi

2019/06/06 06:32

boxplot の order 引数で棒グラフの順番 (この場合、price) を指定できます。 そこに、copied["price"].iloc[::-1] で price の値を逆順にして渡せばよいです。 回答のコードを修正しました。
yu_2_8_2

2019/06/06 06:35

ありがとうございます 降順になりました!
yu_2_8_2

2019/06/06 08:26

たびたびすいません。 扱う配列の行が膨大になってくるとそれに対応してy軸の目盛りも増え、文字が潰れてしまうようになってしまいました。 binsを使い間隔を空けようとしましたが、barplotにはないようなのですが、どのように解決したらよいでしょうか?
tiitoi

2019/06/06 09:00

間隔を空ける方法を追記しました。
yu_2_8_2

2019/06/06 09:35

ありがとうございます! さっそくやってみます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問