python-3.x 如何向使用updatemenus显示数据子集的散点图对象添加OLS趋势线?

irtuqstp  于 2023-02-01  发布在  Python
关注(0)|答案(2)|浏览(154)

我试图使一个plotly散点图与OLS趋势线,并提供了一个下拉菜单,让用户选择从不同的X和Y的。该图几乎工作。其中第一个数字产生的代码有数据和趋势线,但当你选择一个选项,从下拉趋势线,而不是连接每做另一个点,看起来与坐标在 Dataframe 中出现的顺序相同。

密码:

import plotly.graph_objects as go
import plotly.express as px
#making a figure
fig = go.Figure()
x1 = df['crttotal']
x2 = df['nfcc_mean']
x3 = df['bficonmean']
x4 = df['bfiopmean']

y1 = df['avg_misperception_score']
y2 = df['avg_ambiguous_score']

fig = px.scatter(df, x=x2, y=y1, trendline="ols", trendline_scope="overall")

#making the dropdown
fig.update_layout(
    updatemenus=[
        go.layout.Updatemenu(
            type="dropdown",
            buttons=list([

                dict(label="NFCC vs Misperception",
                     method="update",
                     args=[{"x": [x2], "y": [y1], "trendline":["ols"], "trendline_scope":["overall"]},
                           {"title": "NFCC vs Misperception"}]),
                dict(label="CRT vs Misperception",
                     method="update",
                     args=[{"x": [x1], "y": [y1], "trendline":["ols"], "trendline_scope":["overall"]},
                           {"title": "CRT vs Misperception"}]),
                dict(label="bficonmean vs Misperception",
                     method="update",
                     args=[{"x": [x3], "y": [y1], "trendline":["ols"], "trendline_scope":["overall"]},
                           {"title": "bficonmean vs Misperception"}]),
                dict(label="bfiopmean vs Misperception",
                     method="update",
                     args=[{"x": [x4], "y": [y1], "trendline":["ols"], "trendline_scope":["overall"]},
                           {"title": "bfiopmean vs Misperception"}]),

                dict(label="CRT vs Ambiguity",
                     method="update",
                     args=[{"x": [x1], "y": [y2], "trendline":["ols"], "trendline_scope":["overall"]},
                           {"title": "CRT vs Ambiguity"}]),
                dict(label="NFCC vs Ambiguity",
                     method="update",
                     args=[{"x": [x2], "y": [y2], "trendline":["ols"], "trendline_scope":["overall"]},
                           {"title": "NFCC vs Ambiguity"}]),
                dict(label="bficonmean vs Ambiguity",
                     method="update",
                     args=[{"x": [x3], "y": [y2], "trendline":["ols"], "trendline_scope":["overall"]},
                           {"title": "bficonmean vs Ambiguity"}]),
                dict(label="bfiopmean vs Ambiguity",
                     method="update",
                     args=[{"x": [x4], "y": [y2], "trendline":["ols"], "trendline_scope":["overall"]},
                           {"title": "bfiopmean vs Ambiguity"}])

            ])
        )
    ]
)

#set the title
fig.update_layout(title="Dropdown")

fig.show()

数据

crttotal  nfcc_mean  bficonmean  bfiopmean  avg_misperception_score  \
0         3       2.87       3.875      3.000                   -0.062   
1         0       3.53       3.625      3.125                   -0.235   
2         0       3.80       4.000      3.000                    0.077   
3         0       3.73       3.750      3.500                    0.067   
4         2       3.87       3.125      3.000                    0.368   
5         0       3.47       2.750      3.500                   -0.200   
6         0       4.33       3.625      3.625                   -0.200   
7         0       4.13       3.250      3.125                   -0.500   
8         0       4.73       3.250      3.250                   -0.643   
9         3       5.20       3.750      2.750                    0.000   

   avg_ambiguous_score  
0                 2.60  
1                 2.10  
2                 3.35  
3                 2.55  
4                 2.90  
5                 2.80  
6                 2.85  
7                 3.30  
8                 3.15  
9                 2.70

我所期待的(以及运行上述代码时最初显示的内容)enter image description here
当我从下拉列表中选择一个选项时,我会得到什么:enter image description here

9cbw7uwe

9cbw7uwe1#

简短回答

{"x": [x2, <regression x>], "y": [y1, <regression y>], ...}中的"x""y"列表中添加更多数据以显示趋势线。当然,您需要以某种方式计算这些值。下面的建议显示了一种可能的方法。

细节

单击按钮选项后看不到趋势线的原因是中没有趋势线的定义和/或数据,例如:

args=[{"x": [x2], "y": [y1], "trendline":["ols"], "trendline_scope":["overall"]},
                           {"title": "NFCC vs Misperception"}]

这不是很明显,但您可以通过在与"x""y"相关的列表中添加更多数据,轻松地在单击按钮创建的布局中添加更多迹线的数据,如下所示:

args=[{"x": [x2, x21], "y": [y1, y11], "trendline":["ols"], "trendline_scope":["overall"]},
                           {"title": "NFCC vs Misperception"}]
  • 如何 * 创建数据由您决定。但是坚持使用Plotly Express,您可以为OLS回归创建和检索数据,如下所示:
px.scatter(x=x2, y=y1, trendline='ols').data[1].x

以及:

px.scatter(x=x2, y=y1, trendline='ols').data[1].y

这样,第一个按钮的args就像这样:

args=[{"x": [x2, px.scatter(x=x2, y=y1, trendline='ols').data[1].x], "y": [y1, px.scatter(x=x2, y=y1, trendline='ols').data[1].y], "trendline":["ols"], "trendline_scope":["overall"]},
    {"title": "NFCC vs Misperception"}]

下面是前两个按钮的完整设置,其中包含一些随机数据:

图1:

图2:

如果你能把你的数据***和df.to_dict()的输出分享在你的代码片段***中,我可能会找到时间写一个完整的解决方案。

代码:

import plotly.graph_objects as go
import plotly.express as px
import numpy as np
import pandas as pd
# making a figure

df = pd.DataFrame({'crttotal': np.random.random(8),
                   'nfcc_mean': np.random.random(8),
                   'bficonmean': np.random.random(8),
                   'bfiopmean': np.random.random(8),
                   'avg_misperception_score': np.random.random(8),
                   'avg_ambiguous_score': np.random.random(8)})

fig = go.Figure()
x1 = df['crttotal']
x2 = df['nfcc_mean']
x3 = df['bficonmean']
x4 = df['bfiopmean']

y1 = df['avg_misperception_score']
y2 = df['avg_ambiguous_score']

fig = px.scatter(df, x=x2, y=y1, trendline="ols", trendline_scope="overall")
fig.show()
# making the dropdown

fig.update_layout(
    updatemenus=[
        go.layout.Updatemenu(
            type="dropdown",
            buttons=list([

                dict(label="NFCC vs Misperception",
                     method="update",
                     args=[{"x": [x2, px.scatter(x=x2, y=y1, trendline='ols').data[1].x], "y": [y1, px.scatter(x=x2, y=y1, trendline='ols').data[1].y], "trendline":["ols"], "trendline_scope":["overall"]},
                           {"title": "NFCC vs Misperception"}]),
                dict(label="CRT vs Misperception",
                     method="update",
                     args=[{"x": [x1, px.scatter(x=x1, y=y1, trendline='ols').data[1].x], "y": [y1, px.scatter(x=x1, y=y1, trendline='ols').data[1].y], "trendline":["ols"], "trendline_scope":["overall"]},
                           {"title": "CRT vs Misperception"}]),
                # dict(label="bficonmean vs Misperception",
                #      method="update",
                #      args=[{"x": [x3], "y": [y1], "trendline":["ols"], "trendline_scope":["overall"]},
                #            {"title": "bficonmean vs Misperception"}]),
                # dict(label="bfiopmean vs Misperception",
                #      method="update",
                #      args=[{"x": [x4], "y": [y1], "trendline":["ols"], "trendline_scope":["overall"]},
                #            {"title": "bfiopmean vs Misperception"}]),

                # dict(label="CRT vs Ambiguity",
                #      method="update",
                #      args=[{"x": [x1], "y": [y2], "trendline":["ols"], "trendline_scope":["overall"]},
                #            {"title": "CRT vs Ambiguity"}]),
                # dict(label="NFCC vs Ambiguity",
                #      method="update",
                #      args=[{"x": [x2], "y": [y2], "trendline":["ols"], "trendline_scope":["overall"]},
                #            {"title": "NFCC vs Ambiguity"}]),
                # dict(label="bficonmean vs Ambiguity",
                #      method="update",
                #      args=[{"x": [x3], "y": [y2], "trendline":["ols"], "trendline_scope":["overall"]},
                #            {"title": "bficonmean vs Ambiguity"}]),
                # dict(label="bfiopmean vs Ambiguity",
                #      method="update",
                #      args=[{"x": [x4], "y": [y2], "trendline":["ols"], "trendline_scope":["overall"]},
                #            {"title": "bfiopmean vs Ambiguity"}])

            ])
        )
    ]
)

# set the title
fig.update_layout(title="Dropdown")

# fig.show()
j9per5c4

j9per5c42#

"如评论中所述",您的解决方案有效,但趋势线信息框始终显示相同的公式:平均错误感知=-.004 * 病例总数+.073
如何获取它以便信息框也更新?![趋势线信息框不匹配图形变量][1]][1][![趋势线信息框不匹配图形变量][2]][2]
说真的,你太棒了。感谢你提供了如此清晰的答案。[1]:https://i.stack.imgur.com/zPxBL.png [2]:https://i.stack.imgur.com/fy7m6.png
编辑:数据点标签也是如此。当你把鼠标悬停在一个数据上时,它们的值被标记为"crttotal"和"avg_misperception_score"。我想我需要更新布局属性中的一些东西-www.example.com也试图自己弄清楚-只是对plotly来说是新的。https://plotly.com/python/figure-structure/#the-toplevel-layout-attribute? trying to figure it out on my own as well - just new to plotly.

相关问题