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

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

詳細はこちら
Matplotlib

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

Python 3.x

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

1回答

835閲覧

Matplotlibを使用して、コラムの値ごとにグラフを描画する。

Danrussia

総合スコア44

Matplotlib

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

Python 3.x

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2019/10/15 14:55

編集2019/10/15 22:29

###最初に
自分の言語能力が低いのと、実装したい事が幾らか抽象的なので、伝わりづらい所があったら、遠慮なく指摘していただけたら幸いです。

前提・実現したいこと

Python3.7で下記のdfの "BeanNumber_vert"ごとにfor文でグラフを描画させ、.jpg形式で保存するというコードを考えています。

Python3

1df = pd.DataFrame( 2 { 3 "Weight(g)": [0.43, 0.4, 0.45, 0.4, 0.35, 0.5, 0.35, 0.51, 0.43], 4 "Long Axis": [0.92, 0.9, 1.04, 0.97, 0.97, 0.8, 0.97, 1.21, 0.92], 5 "Short Axis": [0.91, 0.89, 0.97, 0.92, 0.88, 0.7, 0.88, 0.95, 0.85], 6 "Grain Thickness": [0.73, 0.56, 0.63, 0.74, 0.51, 0.6, 0.51, 0.77, 0.83], 7 "BeanNumber_vert": ["B2", "B2", "B2", "B3", "B3", "B3", "B4", "B4", "B4"], 8 "Sample":["iris","iris","iris","spider lily","spider lily","spider lily","white spider lily","white spider lily","white spider lily"], 9 "Color Code":["#FFD700","#FFD700","#FFD700","#000000","#000000","#000000","#B22222","#B22222","#B22222"] 10 } 11) 12

できている事

関数の引数に「対象とするデータセット」と「解析したいデータ」の<"BeanNumber_vert">を入力すると、
データセットの[Long Axis],[Short Axis],[Grain Thicknes] のヒストグラムを生成し、["Color Code"]でヒストグラム
の色を決定、["Sample"]をもとに軸名を制定する。
(例: plot(df,bean_number="B2") )
イメージ説明
という関数を作成しました。
(参考:https://teratail.com/questions/202186)

Python3

1def plot(data, bean_number): 2 df = data[data["BeanNumber_vert"] == bean_number] 3 if df.empty: 4 print(f"bean number {bean_number} does not exist in the data frame.") 5 return 6 bean_name = df.iloc[0]["Sample"] 7 bean_number = df.iloc[0]["BeanNumber_vert"] 8 bean_color =df.iloc[0]["Color Code"] 9 # ------------------------------------- 10 11 fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(40, 10)) 12 plt.subplots_adjust(wspace=0.3, hspace=0.2) 13 14 ax1.set_xlabel("長軸(cm)") 15 ax1.set_ylabel("個数(個)") 16 ax1.set_title(f"{bean_name} の長軸_{bean_number}") 17 ax1.hist(df['Long Axis'],range=(0.4, 1.4), bins=11, rwidth=0.7,edgecolor="k",color=f"{bean_color}") 18 19 ax2.set_xlabel("短軸(cm)") 20 ax2.set_ylabel("個数(個)") 21 ax2.set_title(f"{bean_name} の短軸_{bean_number}") 22 ax2.hist(df["Short Axis"],range=(0.4, 1.4),bins=11, rwidth=0.8, edgecolor="k", color=f"{bean_color}") 23 24 ax3.set_xlabel("粒厚(cm)") 25 ax3.set_ylabel("個数(個)") 26 ax3.set_title(f"{bean_name} の粒厚_{bean_number}") 27 ax3.hist(df["Grain Thickness"],range=(0.4, 1.4),bins=11, rwidth=0.8, edgecolor="k", color=f"{bean_color}") 28 plt.savefig(f"bean_number_{bean_number}.jpg")

今できていない事(これから実装したい事)

現在は、関数に"BeanNumber_vert"の数をベタ打ちし可視化しています。
(関数に"B2"を入力するとデータセット内にあるB2を抽出しヒストグラムを作成する。)

関数に直接ベタ打ちをする方法では、毎度"BeanNumber_vert"を入力しなければいけないので、
この部分に関してfor文で一括に可視化し一括で画像を保存したいと思っています。
(for文でB2,B3,B4 を順々に入力させ、可視化し.jpgで各々保存する)

実際には以下の様な流れで実装しようと考えました。
0. dfから"BeanNumber_vert"をリスト(Label)として抽出
0. ブーリアンインデックスでLabelとdfと"BeanNumber_vert"の値が一致ものを取り出す
0. 「2.」をMatplotlibで描画させる。
0. 上記の過程をfor文を用いて、dfの全ての"BeanNumber_vert"に関してMatplotlibで描画させる。

実際にはコードを書く上で、↑の「1.」の部分が上手く実装できていないのか上手く作動させる事ができませんでした。

Python3

1for Label,data in zip(df["BeanNumber_vert"],df): 2 fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(40, 10)) 3 bean_number = df.iloc[0]["BeanNumber_vert"] 4 bean_number = df.iloc[0]["BeanNumber_vert"] 5 bean_color =df.iloc[0]["Color Code"] 6 [df["BeanNumber_vert"]==Label] 7 df1 = data[data["BeanNumber_vert"]==Label] 8 ax1.hist(df1("Long Axis"),color=f"{bean_color}") 9 plt.savefig(f"bean_number_{bean_number}.jpg")

発生している問題・エラーメッセージ

--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-52-88d6d44357b1> in <module>() 1 for data,Label in zip(df,grouped_df): ----> 2 df1 = data[data["BeanNumber_vert"]==Label] 3 df1.hist("Long Axis") 4 plt.savefig(f"bean_number_{bean_number}.jpg") TypeError: string indices must be integers string indices must be integers

試したこと(追記)

for Label,data in zip(df["BeanNumber_vert"],df): bean_number = df.iloc[0]["BeanNumber_vert"] [df["BeanNumber_vert"]==Label]★

"★"の部分でdfの"BeanNumber_vert"をList型として取り出せてないため、上記の様なエラーコードが発生していると思ったのですが、エラーコードを見るに、ブーリアンインデックスでは文字型ではなく、整数型として要求されてました。

for Label in df["BeanNumber_vert"]: [df["BeanNumber_vert"]==Label] type(label) >>>str

そこで簡易的に上記の様なコードを実装して、Labelのtypeを判別した所、str型でした。
float(Label)で整数型に変換する事を試みたのですが、上手くいきませんでした。

補足情報(FW/ツールのバージョンなど)

Anaconda
Python
Pycharm
直接的な解決案の回答でなくとも、参考になりそうなサイト、類似の事例を教えて頂けると幸いです。
お忙しいとは思いますが、よろしくお願いいたします。
情報に不足がありましたら、ご指摘お願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

やりたいことは DataFrame.groupby() を使うと比較的簡単に実装できるかと思います。

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html

これによりコードは

Python

1for label, data in df.groupby("BeanNumber_vert"): 2 bean_name = data.iloc[0]["Sample"] 3 bean_number = label 4 bean_color = data.iloc[0]["Color Code"] 5 # 以下は動作確認コード 6 # print(f'NAME : {bean_name}') 7 # print(f'NUMBER : {bean_number}') 8 # print(f'COLOR : {bean_color}') 9 # print(data) 10 # print("-----------")

のように実装でき、これにより元のdfBeanNumber_vert の値によって分割し、BeanNumber_vert の種類分だけループを回すことができます


あと補足ですが、横並びの3つのグラフもループを使ったほうが簡潔になりますのでまとめるとこんな感じになりますでしょうか。

Python

1for label, data in df.groupby("BeanNumber_vert"): 2 bean_name = data.iloc[0, data.columns.get_loc("Sample")] 3 bean_number = label 4 bean_color =data.iloc[0, data.columns.get_loc("Color Code")] 5 6 fig, axs = plt.subplots(1, 3, figsize=(40, 10)) 7 plt.subplots_adjust(wspace=0.3, hspace=0.2) 8 9 target_names = ['長軸', '短軸', '粒厚'] 10 target_cols = ['Long Axis','Short Axis','Grain Thickness'] 11 for name, col, ax in zip(target_names, target_cols, axs): 12 ax.set_xlabel("{name}(cm)") 13 ax.set_ylabel("個数(個)") 14 ax.set_title(f"{bean_name}{name}_{bean_number}") 15 ax.hist(data[col],range=(0.4, 1.4), bins=11, rwidth=0.7,edgecolor="k",color=f"{bean_color}") 16 17 plt.savefig(f"bean_number_{bean_number}.jpg")

投稿2019/10/16 01:35

magichan

総合スコア15898

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

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

Danrussia

2019/10/16 10:31

回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問