Plotly:带有下拉菜单的散点图,用于更改数据和计算的注释
Plotly: Scatter plot with dropdown menu to change data and calculated annotation
我正在尝试使用 2 个下拉菜单制作一个散点图,其中 select 一个数据列(来自 pandas 数据框)用于绘制 x 轴和 y 轴。我还希望绘图具有随下拉列表 selection 变化的相关统计注释,因为注释是根据 x 和 y 数据作为参数计算的。第一部分我已经设法用下面的代码示例完成了,但我正在努力处理注释。
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)])
我的想法是首先定义一个函数,它将从 figure data structure (hoping that the dropdown selection change this attributes) and returns the text annotation. Then, based on the plotly reference example 中获取 x 和 y 属性,将注释添加到 args
并将按钮的方法更改为 'update'.但是,情况似乎并非如此,注释是静态的。任何人都知道我如何实现这一目标?这是函数和最终代码:
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)])
And the final result
由于我们需要为它们中的每一个创建注释,因此我们将按 ABCD 顺序和 DCBA 顺序为 x,y 组合创建 x 轴和 y 轴的注释。我们有相同的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()
我的解决方案是更改为 select 对变量(即同时更改 x 和 y)的单个下拉按钮。对此的一个警告是在处理大型数据集时,因为组合的数量可能会变得非常大,但对于我的情况(~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()
我正在尝试使用 2 个下拉菜单制作一个散点图,其中 select 一个数据列(来自 pandas 数据框)用于绘制 x 轴和 y 轴。我还希望绘图具有随下拉列表 selection 变化的相关统计注释,因为注释是根据 x 和 y 数据作为参数计算的。第一部分我已经设法用下面的代码示例完成了,但我正在努力处理注释。
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)])
我的想法是首先定义一个函数,它将从 figure data structure (hoping that the dropdown selection change this attributes) and returns the text annotation. Then, based on the plotly reference example 中获取 x 和 y 属性,将注释添加到 args
并将按钮的方法更改为 'update'.但是,情况似乎并非如此,注释是静态的。任何人都知道我如何实现这一目标?这是函数和最终代码:
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)])
And the final result
由于我们需要为它们中的每一个创建注释,因此我们将按 ABCD 顺序和 DCBA 顺序为 x,y 组合创建 x 轴和 y 轴的注释。我们有相同的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()
我的解决方案是更改为 select 对变量(即同时更改 x 和 y)的单个下拉按钮。对此的一个警告是在处理大型数据集时,因为组合的数量可能会变得非常大,但对于我的情况(~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()