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

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

ただいまの
回答率

87.35%

Python3.7系で関数の引数を無視する方法

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 476

score 44

実現したいこと,実装にあたっての問題点

Pyton3.7系とmatplotlibを使用してグラフ(散布図)の描画を自動化したいと考えています。
(参考:https://teratail.com/questions/202186)

下記のデータセット(df)の「BeanNumber_vert」を関数の引数に入力すると、自動で複数系列の散布図を作成するコードは完成しています。

しかしながら、現段階の関数では引数に必ず任意の「BeanNumber_vert」を入力する必要があり、
単数での散布図や要素が3つ以上の散布図の実装ができません。

散布図の要素の数に合わせて関数を定義し直すという方法もあるのですが、コードの行数が長くなる、
場合に応じてファイルを呼び出すのが面倒くさい、といった理由で可能な限り一つの関数で完結させたいです。

ソースコード

df = pd.DataFrame({
    "Weight(g)": [0.43, 0.4, 0.45, 0.4, 0.35, 0.5, 0.35, 0.51, 0.43],
    "Long Axis": [0.92, 0.9, 1.04, 0.97, 0.97, 0.8, 0.97, 1.21, 0.92],
    "Short Axis": [0.91, 0.89, 0.97, 0.92, 0.88, 0.7, 0.88, 0.95, 0.85],
    "Grain Thickness": [0.73, 0.56, 0.63, 0.74, 0.51, 0.6, 0.51, 0.77, 0.83],
    "BeanNumber_vert": ['B2', 'B2', 'B2', 'B6', 'B6', 'B6','B39', 'B39', 'B39']})


def plot(data, B1,B2):

    #該当のデータセットを読み込ませる
    df1 = data[data["BeanNumber_vert"] == B1]
    df2 = data[data["BeanNumber_vert"] == B2]
    if df1.empty:
        print(f"bean number {B2} does not exist in the data frame.")
        return
    if df2.empty:
        print(f"bean number {B2} does not exist in the data frame.")
        return

    # -------------------------------------
    fig, (ax1) = plt.subplots(1, 3, figsize=(35,10))
    plt.subplots_adjust(wspace=0.3, hspace=0.2)

    X1_1 = df1[['Weight(g)']]
    Y1_1 = df1[["Short Axis"]]

    X1_2 = df2[['Weight(g)']]
    Y1_2 = df2[["Short Axis"]]

    ax1.scatter(X1_1, Y1_1, color="b",s=50)
    ax1.scatter(X1_2,Y1_2 , color="r",s=50)
    ax1.set_xlabel("粒重(g)")
    ax1.set_ylabel("短軸(cm)")

plot(df, B1="B2",B2="B6")

エラーメッセージ・試したこと

plot(df, B1="B2")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-43-b6510950b7a2> in <module>()
----> 1 plot(df, B1="B2")

TypeError: plot() missing 1 required positional argument: 'B2'


関数に引数を一つしか渡さない場合、上記の様なエラーが発生したので、関数に引数が一つしか渡されなくてもエラーが無視され関数の実行が行われる方向性で問題の解決を試みました。
(errors="ignore"の様なイメージで)

Googleで「missing 1 required positional argument」といった形で検索したのですが、自分の
調べた範囲では、引数をきちっと渡すといったような解決策しか見つけられませんでした。

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Danrussia

    2019/09/17 19:07

    t_obraさんへ
    plotの実装だけだったら確かにfor文を使った方が間違いなく短時間で実装できるのですが、このコードを書いた(教えて頂いた)当初はブーリアンインデックスの理解に四苦八苦していた、for文の動作イメージをイメージしずらいといった背景があったので、このような形でやっています。
    少しひと段落したら、リストを渡してのループ処理も検討します。

    キャンセル

  • Danrussia

    2019/09/17 19:09

    tetsunosukeさんへ
    回答ありがとうございます。なんとなくの実装のイメージがつかめました。少しこっちの方で頑張ってみます。

    キャンセル

  • Danrussia

    2019/09/17 21:03

    tetsunosukeさんへ
    直接的な解決策は他の方が提示してくださいましたが、可変長引数の存在自体含め知らなかったので、とても勉強になりました。この度はありがとうございました。

    キャンセル

回答 1

checkベストアンサー

+2

リストを使うのが自然な実装だと思います。

import pandas as pd

df = pd.DataFrame(
    {
        "Weight(g)": [0.43, 0.4, 0.45, 0.4, 0.35, 0.5, 0.35, 0.51, 0.43],
        "Long Axis": [0.92, 0.9, 1.04, 0.97, 0.97, 0.8, 0.97, 1.21, 0.92],
        "Short Axis": [0.91, 0.89, 0.97, 0.92, 0.88, 0.7, 0.88, 0.95, 0.85],
        "Grain Thickness": [0.73, 0.56, 0.63, 0.74, 0.51, 0.6, 0.51, 0.77, 0.83],
        "BeanNumber_vert": ["B2", "B2", "B2", "B6", "B6", "B6", "B39", "B39", "B39"],
    }
)


def plot(data, bean_numbers):
    fig, ax = plt.subplots()

    for number in bean_numbers:
        df = data[data["BeanNumber_vert"] == number]
        ax.scatter(df["Weight(g)"], df["Short Axis"], s=50, label=number)

    ax.set_xlabel("粒重(g)")
    ax.set_ylabel("短軸(cm)")
    ax.legend()


plot(df, ["B2", "B6"])

イメージ説明

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/17 21:01

    回答ありがとうございます。恐らく先ほどの方が仰っていたリストを使っての実装法って多分この事なんですね。可読性が高くてシンプルなコードで参考になります。

    キャンセル

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

  • ただいまの回答率 87.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る