I am trying to make a plotly scatter plot with a OLS trendline and provide a dropdown menu what let's the user pick from a different of X's and Y's. The plot almost works. Where the first figure produced by the code has the data and the trendline, but when you choose an option from the drop down the trendline instead connects every done with another dot, seeminly in the order the coordinated appear in the data frame. `
The code:
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()
the Data
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
What I was expecting (and what initially shows when i run the above code)
Plot2:
If you would share your data in your code snippet with the output from df.to_dict()
I might find the time to write up a complete solution.
Code:
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()
CodePudding user response:
"AS DISCUSSED IN COMMENT" your solution worked, but the trenline info box always reads with the same equation: avg_misperception = -.004*crttotal .073
How do I get it so that the info box also updates? [![Trendline info box does not match graph variables][1]][1] [![Trendline info box does not match graph variables][2]][2]
Seriously, you're amazing. TY so much for providing such a clear answer. [1]: https://i.stack.imgur.com/zPxBL.png [2]: https://i.stack.imgur.com/fy7m6.png
EDIT: the same is the case for the data point labels. When you hover over a data their values are labeled as "crttotal" and "avg_misperception_score." I assume I need to update something in the Layout Attribute - https://plotly.com/python/figure-structure/#the-toplevel-layout-attribute? trying to figure it out on my own as well - just new to plotly.