简体   繁体   English

Plotly:分散 plot 下拉菜单更改数据和计算注释

[英]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)])

And the final result而最后的结果

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM