masu333333
@masu333333

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Pythonのライブラリpandas、matplotlib、PySimpleGUIを使ったことある方に相談

解決したいこと

Pythonのライブラリpandas、matplotlib、PySimpleGUIを使ったことある方に相談です。

発生している問題・エラー

以下のコードを実行し、ウィンドウにあるリストボックスから"腹囲(cm)"を選択してボタンを押すと、不本意にも身長と体重の折れ線グラフも一緒に表示されてしまいます(選択した"腹囲(cm)"の折れ線グラフだけ表示されるようにしたいです)。原因がわかる方いましたら教えていただけないでしょうか。

該当するソースコード

Python

例)

import PySimpleGUI as sg
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(font=["Meiryo","Yu Gothic"])
sg.theme("DarkBrown3")

data={"year":[2024, 2023, 2022],
      "身長(cm)": [178.6, 177.1 ,176.8],
      "体重(kg)": [54.7, 55.5, 61.3],
      "腹囲(cm)": [64.0, 69.0, 73.3]}
df=pd.DataFrame(data)
col_dict={"身体計測": ["身長(cm)", "体重(kg)", "腹囲(cm)"]}
layout=[[sg.Text("確認したい検査項目を選んでください。")],
[sg.Text("【身体計測】")],
[sg.Listbox(col_dict["身体計測"],size=(20,5),key="name")],
[sg.Button("OK",key="Body_plot"),sg.Text(key="err")]]
window=sg.Window("健康診断結果アプリ",layout,default_element_size=(12, 1))

while True:
    event,values=window.read()
    if values["name"][0]=="身長(cm)" or "体重(kg)":
        if event=="Body_plot":
            fig,ax=plt.subplots(figsize=(11,7))
            ax.plot(df["year"], df["身長(cm)"], marker ="o", linestyle = "-", color ="r")
            ax.set_xlabel('year')
            ax.set_ylabel('身長(cm)', color='r')
            ax.set_yticks(range(170,181,1))
            ax.tick_params('y', colors="r")
            ax.set_ylim(170, 181)
            plt.axhline(y=171,c="r",linestyle="--")
            ax2=ax.twinx()
            ax2.plot(df["year"], df["体重(kg)"], marker ="x", linestyle = "-", color ="b")
            ax2.set_ylabel('体重(kg)', color='b')
            ax2.set_yticks(range(50,66,1))
            ax2.tick_params('y', colors="b")
            ax2.set_ylim(50, 66)
            ax2.grid(False)
            plt.title("日本の成人男性平均身長:171cm")
            plt.show()
            print(values["name"][0])
            
    if values["name"][0]=="腹囲(cm)":
        if event=="Body_plot":
            fig,ax=plt.subplots(figsize=(11,7))
            ax.plot(df["year"], df["腹囲(cm)"], marker ="o", linestyle = "-")
            ax.set_xlabel('year')
            ax.set_ylabel('腹囲(cm)')
            ax.set_yticks(range(60,76,1))
            ax.tick_params('y')
            ax.set_ylim(60, 76)
            plt.title("成人男性の腹囲が85cm以上なら、メタボリックシンドロームの診断基準に該当する可能性あり")
            plt.show()
            print(values["name"][0])
            
window.close()
0

2Answer

前段のifのインデントがわからないので、答えにくそうな気がします。
コードをコードブロック```で挟み、インデントが分かるようにした方がいいのでは?

1Like

Comments

  1. @masu333333

    Questioner

    ありがとうございます。編集してみます。

print(values["name"][0])を入れて、どのような値になっているか確認されてはいかがでしょうか

1Like

Comments

  1. @masu333333

    Questioner

    最後から2行目にprint(values["name"][0])を追加して実行してみました。
    リストボックスで選んだ通りに文字列が表示されているので、リストボックスで選んだ内容は正しく認識されているようです。

  2. それぞれのIFの中にいれて、どこを通っているか確認されては?

  3. それとも、そもそもどちらも描画されていて、どちらを通ろうが必ずどちらもでてしまうのでしょうか
    わたしはどのライブラリにも詳しくないので、お役に立てそうにないですね

  4. @masu333333

    Questioner

    結論から申し上げると、いただいたコメントのおかげで解決できました。

    まず、試しにそれぞれのif文の文末にprint(values["name"][0])を入れて実行してみました。
    リストボックスから"身長(cm)"あるいは"体重(kg)"を選んだときは選んだ通りに文字列が表示されましたが、"腹囲(cm)"を選んだときは"腹囲(cm)"という文字列が2回続けて表示されました。つまり、どっちのif文もtrue扱いになっていることがわかりました。2つ目のif文はともかく、どうして1つ目のif文がtrue扱いになってしまってるのか考えてみたところ、"体重(kg)"の文字列にvalues["name"][0]==がかかっておらず、ただの文字列としてプログラムに認識されていたようです。私としてはうっかり付け忘れたとかではなくて、質問文に挙げたコードの内容で、
    values["name"][0]==が"身長(cm)"だけでなく、"体重(kg)"にもかかっているものと思ってました。なので、もともとのコードは下記のように直しました。

    誤)if values["name"][0]=="身長(cm)" or "体重(kg)":

    正)if values["name"][0]=="身長(cm)" or values["name"][0]=="体重(kg)":

    元の間違っているif文だと、リストボックスで何を選んだかに関わらず、無条件にtureが成立してしまうんですね。念のため、IDLE Shellにて下記のコードを実行してみたら文字列が表示されたのでそういう解釈で良さそうです。。

    if "体重(kg)": #trueなら文字列が表示される
    print("体重(kg)")

    助言のおかげで原因にたどり着きました。ありがとうございました(まだ見てるかわかりませんが)。

Your answer might help someone💌