带有 ipywidgets 的交互式 plotly boxplot
Interactive plotly boxplot with ipywidgets
我正在尝试使用 ipywidgets 和 Plotly 创建交互式箱线图。
我从 this example
开始
虽然这很好,但我想根据下拉输入更改箱线图的分组。
有了 interact
我可以做到这一点:
import datetime
import numpy as np
import pandas as pd
import plotly.graph_objects as go
from ipywidgets import widgets
df = pd.read_csv(
'https://raw.githubusercontent.com/yankev/testing/master/datasets/nycflights.csv')
df = df.drop(df.columns[[0]], axis=1)
from ipywidgets import interact
def view_image(col):
fig = go.FigureWidget()
for val in df[col].unique():
groupData = df.query(f'{col} == "{val}"')
fig.add_trace(
go.Box(y = groupData['distance'],
name = val)
)
fig.show()
interact(view_image, col = ['origin', 'carrier'])
结果是我可以更改数据分组所依据的列。
但是,我想对小部件有更多的控制,就像在官方示例中那样。
这就是我正在尝试的(但失败了):
# Assign an empty figure widget with two traces
gdata = []
for origin in df.origin.unique():
groupData = df.query(f'origin == "{origin}"')
gdata.append(
go.Box(y = groupData['distance'],
name = origin)
)
g = go.FigureWidget(data=gdata,
layout=go.Layout(
title=dict(
text='NYC FlightDatabase'
),
barmode='overlay'
))
def response_box(change):
col = column.value
with g.batch_update():
gdata = []
for val in df[col].unique():
groupData = df.query(f'{col} == "{val}"')
gdata.append(
go.Box(y = groupData['distance'],
name = val)
)
g.data = gdata
column = widgets.Dropdown(
options=['origin','carrier']
)
column.observe(response_box, 'value')
container2 = widgets.HBox([column])
widgets.VBox([container2,
g])
请注意,由于我有新的分组,我不能只进入 g.data[index].y
并更改每个索引,但我必须像在 interact
函数中那样重新生成图形。
这个特定的迭代给我一个“你不能直接更新数据”的错误。我尝试了几种不同的方法,但我似乎没有找到一种有效的方法。
有什么想法吗?
- 不清楚您想如何与数据维度进行交互。所以我已经定义了图形的 x 和 color,加上按 origin, dest, carrier[=25= 过滤]
- 使用 Plotly Express 创建箱形图要简单得多,所以使用了
- 然后它真正简化了参数传递。已使用 https://ipywidgets.readthedocs.io/en/latest/examples/Using%20Interact.html 和 decorator
import datetime
import numpy as np
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
from ipywidgets import widgets
from ipywidgets import interact
df = pd.read_csv(
"https://raw.githubusercontent.com/yankev/testing/master/datasets/nycflights.csv"
)
df = df.drop(df.columns[[0]], axis=1)
@interact
def view_image(
col=widgets.Dropdown(
description="Plot:", value="carrier", options=["origin", "carrier"]
),
filtercol=widgets.Dropdown(
description="Filter by:", value="carrier", options=["origin", "dest", "carrier"]
),
filter=widgets.Text(
description="Filter:", value=""
),
):
# check if filter results in any rows... if not all data...
if df[filtercol].eq(filter).any():
dfp = df.loc[df[filtercol].eq(filter)]
else:
dfp = df
fig = px.box(dfp, x=col, y="distance", color=col)
go.FigureWidget(fig.to_dict()).show()
我正在尝试使用 ipywidgets 和 Plotly 创建交互式箱线图。
我从 this example
开始虽然这很好,但我想根据下拉输入更改箱线图的分组。
有了 interact
我可以做到这一点:
import datetime
import numpy as np
import pandas as pd
import plotly.graph_objects as go
from ipywidgets import widgets
df = pd.read_csv(
'https://raw.githubusercontent.com/yankev/testing/master/datasets/nycflights.csv')
df = df.drop(df.columns[[0]], axis=1)
from ipywidgets import interact
def view_image(col):
fig = go.FigureWidget()
for val in df[col].unique():
groupData = df.query(f'{col} == "{val}"')
fig.add_trace(
go.Box(y = groupData['distance'],
name = val)
)
fig.show()
interact(view_image, col = ['origin', 'carrier'])
结果是我可以更改数据分组所依据的列。
但是,我想对小部件有更多的控制,就像在官方示例中那样。
这就是我正在尝试的(但失败了):
# Assign an empty figure widget with two traces
gdata = []
for origin in df.origin.unique():
groupData = df.query(f'origin == "{origin}"')
gdata.append(
go.Box(y = groupData['distance'],
name = origin)
)
g = go.FigureWidget(data=gdata,
layout=go.Layout(
title=dict(
text='NYC FlightDatabase'
),
barmode='overlay'
))
def response_box(change):
col = column.value
with g.batch_update():
gdata = []
for val in df[col].unique():
groupData = df.query(f'{col} == "{val}"')
gdata.append(
go.Box(y = groupData['distance'],
name = val)
)
g.data = gdata
column = widgets.Dropdown(
options=['origin','carrier']
)
column.observe(response_box, 'value')
container2 = widgets.HBox([column])
widgets.VBox([container2,
g])
请注意,由于我有新的分组,我不能只进入 g.data[index].y
并更改每个索引,但我必须像在 interact
函数中那样重新生成图形。
这个特定的迭代给我一个“你不能直接更新数据”的错误。我尝试了几种不同的方法,但我似乎没有找到一种有效的方法。
有什么想法吗?
- 不清楚您想如何与数据维度进行交互。所以我已经定义了图形的 x 和 color,加上按 origin, dest, carrier[=25= 过滤]
- 使用 Plotly Express 创建箱形图要简单得多,所以使用了
- 然后它真正简化了参数传递。已使用 https://ipywidgets.readthedocs.io/en/latest/examples/Using%20Interact.html 和 decorator
import datetime
import numpy as np
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
from ipywidgets import widgets
from ipywidgets import interact
df = pd.read_csv(
"https://raw.githubusercontent.com/yankev/testing/master/datasets/nycflights.csv"
)
df = df.drop(df.columns[[0]], axis=1)
@interact
def view_image(
col=widgets.Dropdown(
description="Plot:", value="carrier", options=["origin", "carrier"]
),
filtercol=widgets.Dropdown(
description="Filter by:", value="carrier", options=["origin", "dest", "carrier"]
),
filter=widgets.Text(
description="Filter:", value=""
),
):
# check if filter results in any rows... if not all data...
if df[filtercol].eq(filter).any():
dfp = df.loc[df[filtercol].eq(filter)]
else:
dfp = df
fig = px.box(dfp, x=col, y="distance", color=col)
go.FigureWidget(fig.to_dict()).show()