[英]Plotly: Scatter plot with dropdown menu to change data and calculated annotation
I'm trying to make a scatter plot with 2 dropdown menus that select a data column (from a pandas data frame) to be plotted for x and y-axis.我正在尝试使用 select 数据列(来自 pandas 数据框)为 x 轴和 y 轴绘制 2 个下拉菜单来制作散点图 plot。 I also want the plot to have a correlation stats annotation that change with the dropdown selection, because the annotation is calculated on both the x and y data as parameters.
我还希望 plot 具有随下拉选择而变化的相关统计注释,因为注释是根据 x 和 y 数据作为参数计算的。 The first part I've managed to do with the code example below, but I am struggling with the annotation.
第一部分我已经设法用下面的代码示例完成,但我正在努力处理注释。
import pandas as pd
import numpy as np
import plotly.graph_objects as go
# Prep random data
data = pd.DataFrame(dict(
A=np.random.randint(11, size=10),
B=np.random.randint(11, size=10),
C=np.random.randint(11, size=10),
D=np.random.randint(11, size=10)
))
# Create figure and add one scatter trace
fig = go.Figure()
fig.add_trace(go.Scatter(
x=data['A'],
y=data['A'],
visible=True,
mode='markers',
)
)
# Create x and y buttons
x_buttons = []
y_buttons = []
for column in data.columns:
x_buttons.append(dict(method='restyle',
label=column,
args=[{'x': [data[column]]}]
)
)
y_buttons.append(dict(method='restyle',
label=column,
args=[{'y': [data[column]]}]
)
)
# Pass buttons to the updatemenus argument
fig.update_layout(updatemenus=[dict(buttons=x_buttons, direction='up', x=0.5, y=-0.1),
dict(buttons=y_buttons, direction='right', x=-0.01, y=0.5)])
My idea was to first define a function that will take the x and y attributes from the figure data structure (hoping that the dropdown selection change this attributes) and returns the text annotation.我的想法是首先定义一个 function,它将从图形数据结构中获取 x 和 y 属性(希望下拉选择更改此属性)并返回文本注释。 Then, based on the plotly reference example , add the annotation to
args
and change the method of the buttons to 'update'.然后,基于plotly参考示例,将注释添加到
args
并将按钮的方法更改为'update'。 However, that doesn't seem to be the case and the annotation is static. Anyone has an idea of how I could achieve this?但是,情况似乎并非如此,注释为 static。有人知道我如何实现这一目标吗? Here is the function and the final code:
这是 function 和最终代码:
from scipy import stats
def corr_annotation(x, y):
pearsonr = stats.pearsonr(x, y)
return 'r = {:.2f} (p = {:.3f})'.format(pearsonr[0], pearsonr[1])
import pandas as pd
import numpy as np
import plotly.graph_objects as go
# Prep random data
data = pd.DataFrame(dict(
A=np.random.randint(11, size=10),
B=np.random.randint(11, size=10),
C=np.random.randint(11, size=10),
D=np.random.randint(11, size=10)
))
# Create figure and add one scatter trace
fig = go.Figure()
fig.add_trace(go.Scatter(
x=data['A'],
y=data['A'],
visible=True,
mode='markers',
)
)
fig.add_annotation(dict(text=corr_annotation(fig['data'][0]['x'], fig['data'][0]['y']),
showarrow=False,
yref='paper', xref='paper',
x=0.99, y=0.95))
# Create x and y buttons
x_buttons = []
y_buttons = []
for column in data.columns:
x_buttons.append(dict(method='update',
label=column,
args=[{'x': [data[column]]},
{'annotations': [dict(text=corr_annotation(fig['data'][0]['x'], fig['data'][0]['y']),
showarrow=False,
yref='paper', xref='paper',
x=0.99, y=0.95)]}]
)
)
y_buttons.append(dict(method='update',
label=column,
args=[{'y': [data[column]]},
{'annotations': [dict(text=corr_annotation(fig['data'][0]['x'], fig['data'][0]['y']),
showarrow=False,
yref='paper', xref='paper',
x=0.99, y=0.95)]}]
)
)
# Pass buttons to the updatemenus argument
fig.update_layout(updatemenus=[dict(buttons=x_buttons, direction='up', x=0.5, y=-0.1),
dict(buttons=y_buttons, direction='right', x=-0.01, y=0.5)])
The solution for me was to change to a single dropdown button that select pairs of variables (ie changes both x and y).我的解决方案是更改为单个下拉按钮,该按钮包含 select 对变量(即同时更改 x 和 y)。 One caveat to this is when dealing with large datasets, as the number of combinations can get pretty big, but for my case (~20 columns) it was fine.
对此的一个警告是在处理大型数据集时,因为组合的数量可能会变得非常大,但对于我的情况(~20 列)来说这很好。
from scipy import stats
def corr_annotation(x, y):
pearsonr = stats.pearsonr(x, y)
return 'r = {:.2f} (p = {:.3f})'.format(pearsonr[0], pearsonr[1])
# Prep random data
import pandas as pd
import numpy as np
np.random.seed(12)
data = pd.DataFrame(dict(
A=np.random.randint(11, size=10),
B=np.random.randint(11, size=10),
C=np.random.randint(11, size=10),
D=np.random.randint(11, size=10)
))
# Create base figure
import plotly.express as px
fig = px.scatter(data, x='A', y='B')
fig.add_annotation(dict(text=corr_annotation(data['A'], data['B']),
showarrow=False,
yref='paper', xref='paper',
x=0.99, y=0.95))
# Create buttons
import itertools
buttons = []
for x, y in itertools.combinations(data.columns, 2):
buttons.append(dict(method='update',
label='{} x {}'.format(x, y),
args=[{'x': [data[x]],
'y': [data[y]]},
{'xaxis': {'title': x},
'yaxis': {'title': y},
'annotations': [dict(text=corr_annotation(data[x], data[y]),
showarrow=False,
yref='paper', xref='paper',
x=0.99, y=0.95)]}]
)
)
# Update and show figure
fig.update_layout(updatemenus=[dict(buttons=buttons, direction='down', x=0.1, y=1.15)])
fig.show()
Since we need to create annotations for each of them, we will create annotations for the x-axis and for the y-axis for the x,y combinations in ABCD order and DCBA order.由于我们需要为它们中的每一个创建注释,因此我们将按 ABCD 顺序和 DCBA 顺序为 x,y 组合的 x 轴和 y 轴创建注释。 We have the same R-values, but we have not verified them, so please deal with them yourself.
我们有相同的R值,但我们没有验证过,所以请自行处理。
from scipy import stats
def corr_annotation(x, y):
pearsonr = stats.pearsonr(x, y)
return 'r = {:.2f} (p = {:.3f})'.format(pearsonr[0], pearsonr[1])
import pandas as pd
import numpy as np
import plotly.graph_objects as go
# Prep random data
data = pd.DataFrame(dict(
A=np.random.randint(11, size=10),
B=np.random.randint(11, size=10),
C=np.random.randint(11, size=10),
D=np.random.randint(11, size=10)
))
# Create figure and add one scatter trace
fig = go.Figure()
fig.add_trace(go.Scatter(
x=data['A'],
y=data['A'],
visible=True,
mode='markers',
)
)
fig.add_annotation(dict(text=corr_annotation(fig['data'][0]['x'], fig['data'][0]['y']),
showarrow=False,
yref='paper', xref='paper',
x=0.99, y=0.95))
# Create x and y buttons
x_buttons = []
y_buttons = []
for ncol,rcol in zip(data.columns, data.columns[::-1]):
x_buttons.append(dict(method='update',
label=ncol,
args=[{'x': [data[ncol]]},
{'annotations': [dict(text=corr_annotation(data[ncol], data[rcol]),
showarrow=False,
yref='paper', xref='paper',
x=0.99, y=0.95)]}]
)
)
y_buttons.append(dict(method='update',
label=ncol,
args=[{'y': [data[ncol]]},
{'annotations': [dict(text=corr_annotation(data[rcol], data[ncol]),
showarrow=False,
yref='paper', xref='paper',
x=0.99, y=0.95)]}]
)
)
# Pass buttons to the updatemenus argument
fig.update_layout(updatemenus=[dict(buttons=x_buttons, direction='up', x=0.5, y=-0.1),
dict(buttons=y_buttons, direction='right', x=-0.01, y=0.5)])
fig.show()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.