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

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

ただいまの
回答率

90.51%

  • Python 3.x

    6387questions

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

箱ひげ図のパラメータを動的に変更するためwidgetを追加したら、箱ひげ図が表示されなくなった

解決済

回答 1

投稿 編集

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

H.Kazuyuki

score 12

【やりたいこと】
下記のようなデータに対し、aかbのデータが、ある閾値(2つ)の時に、
それらをhueとして箱ひげ図を描きたいと考えています。
(例えば、aの閾値を30,50とすると、30未満、30~50, 50より大きいもので
箱ひげ図を描画)
これをスライドバー(ipywidgetなど)を用いて動的に変更しながら
グラフを更新したいと考えています。(できればholoviewなどを用いたい)

イメージ(こんな感じ)
イメージ説明

データ(一部)
a    b    c
0    80    3    50
1    50    2    80
2    30    5    30
3    20    1    40
4    40    3    50
5    20    0    90
6    30    0    70
7    70    0    60
8    100    0    20
9    50    0    100

【やってみたこと】
matplotlib(seaborn)では、下記のように書くことで一応はこひげ図はかけたのですが、
ボタンを押すと一回描画のみになってしまい、ボタンが消えてしまいます。

df_boxdraw = pd.read_excel("サンプル.xlsx")

# boxプロット用関数(factorplotで実現ver)
def plot_genre_members(b):
    clear_output()
    df_boxdraw["x_thresh"] = df_boxdraw[types.value].apply(lambda x: 0 if x< th1.value else 1 if x<th2.value else 2)
    ax = sns.factorplot(x="x_thresh", y="b", hue="x_thresh", data=df_boxdraw, kind="box")
    ax.add_legend()
    plt.title("x:" + types.value + ",y:b" + "th1:" + str(th1.value) + "th2:" + str(th2.value))
    plt.show()

types = Dropdown(options=list(df_boxdraw.columns))
submit_button = Button(description='グラフを表示')
th1 = IntSlider(description = "thresh_low")
th2 = IntSlider(description = "thresh_high")
submit_button.on_click(plot_genre_members)
VBox([HBox([types, submit_button]), HBox([th1, th2])])


出来ればボタンなどを出したまま、グラフを更新するような処理にしたいのですが、どのように書けば実現できますでしょうか。

【追記】
色々調べてみたのですが、parambokehというライブラリを使うと、Bokeh+ウィジェットを用いて、aの敷居値を動的に動かしてグラフを更新できそうに思いました。
しかし、下記サンプルをそのままjupyterで実行しても、下記エラーが出てしまい、動かないです。。。

ModuleNotFoundError: No module named 'holoviews.plotting.comms'

エラー内容から見ると、holoviews.plotting.commsのモジュールがないと言われているように見えるんですが、holoviews, parambokehは、conda install -c ioamでインストール済みですので、なぜこのエラーが出るのかまったくわかりません。。。

https://ioam.github.io/parambokeh/user_guide/View_Parameters.html

【追記2】
下記のサイトを見ながら、parambokehのwidgetを出すことは成功したのですが、
今度はholoviewsの箱ひげ図(boxwhisker)が表示されなくなりました…。
参考サイト:
http://holoviews.org/reference/containers/matplotlib/DynamicMap.html
http://holoviews.org/user_guide/Dashboards.html
https://ioam.github.io/parambokeh/user_guide/Introduction.html

ソースコード:

import param
import parambokeh
import numpy as np
import pandas as pd

import holoviews as hv
from bokeh.io import output_notebook

hv.extension('bokeh')
output_notebook()

class TestParmSetting(param.Parameterized):
    df = pd.read_excel("サンプル.xlsx")
    df_boxdraw = df.iloc[:,[13,64,76]].copy() # 必要な要素だけコピーしたdf作成
    sel_list = list(df_boxdraw.columns)

    th1 = param.Number(default=0.1, precedence=0)
    th2 = param.Number(default=0.2, precedence=0)
    par = param.ObjectSelector(default=sel_list[0],objects=sel_list)

    def disp_box():
        #df = pd.DataFrame(getattr(stocks, symbol))
        #df['date'] = df.date.astype('datetime64[ns]')
        return hv.BoxWhisker(df_boxdraw, kdims=['MC率'], vdims=['FL率']).sort()

    def update(self, **kwargs):
        print(self.th1, self.th2, self.par)
        stocks = hv.DynamicMap(self.disp_box, kdims=[], vdims=[])
        return stocks

example = TestParmSetting(name='TestBoxDisp')
layout = parambokeh.Widgets(example, on_init=True, callback=example.update)

どなたかご存知であればご教示いただけると幸甚に存じます。
何卒ご回答のほどよろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

check解決した方法

0

とりあえず、最低限の目的は達したコードがかけました。
いくつか直したい、および追加したい項目があって、そっちはまだ詰まっているのですが、とりあえず、この項目については閉じておきます。
問題点:
①現状、スライダーの値は渡せるようになったが、テキストボックスなどの値は動的に渡せない。
②同様に、ほかの引数を渡せない(渡すとエラーになる)ため、データフレームの読み込み先ファイルを変更できない。

import param
import parambokeh
import numpy as np
import pandas as pd

import holoviews as hv
from bokeh.io import output_notebook

hv.extension('bokeh')
output_notebook()

#th1 = param.Number(default=0.3, precedence=0)
#th2 = param.Number(default=0.2, precedence=0)
#par = param.ObjectSelector(default=sel_list[0],objects=sel_list)


def box_disp(th1, th2):
    df = pd.read_excel("サンプル.xlsx")
    df_boxdraw = df.iloc[:,[13,64,76]].copy() # 必要な要素だけコピーしたdf作成
    sel_list = list(df_boxdraw.columns)
    df_boxdraw["x_thresh"] = df_boxdraw['MC率'].apply(lambda x: 0 if x< th1 else 1 if x<th2 else 2)

    return hv.BoxWhisker(df_boxdraw, kdims=('x_thresh', 'MC率'), vdims=('FL率','FL率'))

#df = pd.read_excel("サンプル.xlsx")
#df_boxdraw = df.iloc[:,[13,64,76]].copy() # 必要な要素だけコピーしたdf作成
#
dmap = hv.DynamicMap(box_disp, kdims=['th1', 'th2'])
dmap.redim.range(th1=(0,50)).redim.range(th2=(0,80))

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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

  • Python 3.x

    6387questions

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