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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

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

Q&A

解決済

1回答

2389閲覧

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

H.K2

総合スコア88

Python 3.x

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

0グッド

0クリップ

投稿2018/06/25 13:21

編集2018/06/30 04:34

【やりたいこと】
下記のようなデータに対し、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)では、下記のように書くことで一応はこひげ図はかけたのですが、
ボタンを押すと一回描画のみになってしまい、ボタンが消えてしまいます。

python3

1df_boxdraw = pd.read_excel("サンプル.xlsx") 2 3# boxプロット用関数(factorplotで実現ver) 4def plot_genre_members(b): 5 clear_output() 6 df_boxdraw["x_thresh"] = df_boxdraw[types.value].apply(lambda x: 0 if x< th1.value else 1 if x<th2.value else 2) 7 ax = sns.factorplot(x="x_thresh", y="b", hue="x_thresh", data=df_boxdraw, kind="box") 8 ax.add_legend() 9 plt.title("x:" + types.value + ",y:b" + "th1:" + str(th1.value) + "th2:" + str(th2.value)) 10 plt.show() 11 12types = Dropdown(options=list(df_boxdraw.columns)) 13submit_button = Button(description='グラフを表示') 14th1 = IntSlider(description = "thresh_low") 15th2 = IntSlider(description = "thresh_high") 16submit_button.on_click(plot_genre_members) 17VBox([HBox([types, submit_button]), HBox([th1, th2])]) 18 19

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

【追記】
色々調べてみたのですが、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)

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

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

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

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

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

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

guest

回答1

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))

投稿2018/06/30 16:27

H.K2

総合スコア88

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問