With this code on the plotly website : https://plotly.com/python/sliders/
Is it possible to add a trace, one for each slider step, once the step is selected? Because if we have a large number of step, it could affect the performance. I have a project and I can't use this method...
import plotly.graph_objects as go
import numpy as np
# Create figure
fig = go.Figure()
# Add traces, one for each slider step
for step in np.arange(0, 5, 0.1):
fig.add_trace(
go.Scatter(
visible=False,
line=dict(color="#00CED1", width=6),
name="𝜈 = " + str(step),
x=np.arange(0, 10, 0.01),
y=np.sin(step * np.arange(0, 10, 0.01))))
# Make 10th trace visible
fig.data[10].visible = True
# Create and add slider
steps = []
for i in range(len(fig.data)):
step = dict(
method="update",
args=[{"visible": [False] * len(fig.data)},
{"title": "Slider switched to step: " + str(i)}], # layout attribute
)
step["args"][0]["visible"][i] = True # Toggle i'th trace to "visible"
steps.append(step)
sliders = [dict(
active=10,
currentvalue={"prefix": "Frequency: "},
pad={"t": 50},
steps=steps
)]
fig.update_layout(
sliders=sliders
)
fig.show()
Related
I am trying to use plotly to plot a graph similar to the one here below:
Unfortunately I am only able to plot something like this
What I would like is to have normal boundaries (upper and lower defined by two dataframe columns and only one entry in the legend.
import plotly.graph_objs as go
# Create a trace for the lower bound
trace1 = go.Scatter(x=df.index,
y=df['lower'],
name='Lower Bound',
fill='tonexty',
fillcolor='rgba(255,0,0,0.2)',
line=dict(color='blue'))
# Create a trace for the median
trace2 = go.Scatter(x=df.index,
y=df['median'],
name='median',
line=dict(color='blue', width=2))
# Create a trace for the upper bound
trace3 = go.Scatter(x=df.index,
y=df['upper'],
name='Upper Bound',
fill='tonexty',
fillcolor='rgba(255,0,0,0.2)',
line=dict(color='blue'))
# Create the layout
layout = go.Layout(xaxis=dict(title='Date'),
yaxis=dict(title='title'))
# Create the figure with the three traces and the layout
fig = go.Figure(data=[trace1, trace2, trace3], layout=layout)
context['pltyplot'] = pltyplot(fig, output_type="div")
I want to use plotly because I am integrating the resulting figure into a django web page and plotly enables, with the las line, to import the whole object in a clean, simple and interactive way into the poge.
Any ideas?
You can try this code:
import plotly.graph_objs as go
x = [1, 2, 3, 4, 5]
y = [2, 4, 5, 3, 6]
# Define the confidence interval
interval = 0.6 * np.std(y) / np.mean(y)
fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=y, mode='lines', name='Line'))
fig.add_trace(go.Scatter(x=x+x[::-1],
y=y+[i + interval for i in y[::-1]],
fill='toself',
fillcolor='rgba(0,100,80,0.2)',
line=dict(width=0),
showlegend=False))
fig.add_trace(go.Scatter(x=x+x[::-1],
y=y+[i - interval for i in y[::-1]],
fill='toself',
fillcolor='rgba(0,100,80,0.2)',
line=dict(width=0),
showlegend=False))
fig.show()
Aim: Having two scatter plots in the same figure while using a slider in Plotly.
Expected behavior: Show a figure with two plots updating simultaneously and sharing the same "slider step".
Current behavior: The slider steps over both scatter plots, separating them and showing one result at a time.
I attach below a minimal reproducible example adapted from the plotly documentation. Instead of simply plotting the sin(x), I also added a second plot with cos(x).
I tried using add_traces(), and also creating two separate traces and the updating them with fig = go.Figure(data=trace_list1+trace_list2) as shown here.
Any help would be much appreciated!
import plotly.graph_objects as go
import numpy as np
# Create figure
fig = go.Figure()
# Add traces, one for each slider step
for step in np.arange(0, 5, 0.5):
fig.add_traces([
go.Scatter(
x=np.arange(0, 10, 0.01),
y=np.sin(step * np.arange(0, 10, 0.01))),
go.Scatter(
x=np.arange(0, 10, 0.01),
y=np.cos(step * np.arange(0, 10, 0.01)))])
# Make 10th trace visible
fig.data[10].visible = True
# Create and add slider
steps = []
for i in range(len(fig.data)):
step = dict(
method="update",
args=[{"visible": [False] * len(fig.data)},
{"title": "Slider switched to step: " + str(i)}], # layout attribute
)
step["args"][0]["visible"][i] = True # Toggle i'th trace to "visible"
steps.append(step)
sliders = [dict(
active=10,
currentvalue={"prefix": "Frequency: "},
pad={"t": 50},
steps=steps
)]
fig.update_layout(
sliders=sliders
)
fig.show()
I enclose the answer given on the forum maintained by the Plotly community.
# Create and add slider
steps = []
for i in range(len(fig.data)):
if i % 2 == 0:
step = dict(
method="update",
args=[{"visible": [False] * len(fig.data)},
{"title": "Slider switched to step: " + str(i/2)}], # layout attribute
)
step["args"][0]["visible"][i] = True # Toggle i'th trace to "visible"
step["args"][0]["visible"][i+1] = True
steps.append(step)
fig = go.Figure()
for r in np.arange(0.05, 0.56, 0.005): #want the steps to show each value in r
xth_r,yth_r,zth_r = coords_theta(r)
fig.add_trace(
go.Scatter(mode="lines",
line=dict(color="#00CED1", width=2.5),
x=th,
y=magB(xth_r,yth_r,zth_r,xpos,ypos,zpos,0.1*165)))
fig.data[10].visible = True
steps = []
for i in range(len(fig.data)):
step = dict(
method="update",
args=[{"visible": [False] * len(fig.data)},
{"title": "R(m) is :" + str(i)}],
)
step["args"][0]["visible"][i] = True
steps.append(step)
sliders = [dict(
active=10,
currentvalue={"prefix": "R: "},
pad={"t": 50},
steps=steps
)]
fig.update_layout(
sliders=sliders
)
fig.show()
The steps show up as integer values, like step-0, step-6. I don't want this, I just want them to be the values in r. I would also like to have the area underneath the slider contain maybe like every 5 values of r, such that it doesn't get overcrowded with numbers.
I'm trying to find a solution within Plotly/Dash where I can filter the incoming data for a plot with the selection of a custom button.
For example, consider the following data:
x | y | Special
.23 .55 N
.11 .89 Y
.45 .34 Y
.91 .21 N
How could I make an 'updatemenu' addition to my plots that displays only the data points where Special='Y' with one button selection or all of the points with another selection'?
What I have now:
my_figure.update_layout(
updatemenus=[
dict(
buttons=list([
dict(
args=[<unknown> (filter function goes here?)],
label="Only Special Data",
method="restyle"
),
dict(
args=[<unknown> (filter function goes here?)],
label="All Data",
method="restyle"
)
]),
),
]
)
I'm new to the custom button feature of Plotly so any help would be greatly appreciated!
You can set up a button for a dataframe subset of each unique element of df['special] with:
buttons = []
# button with one option for each 'special'
for s in df['special'].unique():
buttons.append(dict(method='restyle',
label=s,
visible=True,
args=[{'y':[df[df['special']==s]['y'].values],
'x':[df[df['special']==s]['x'].values],
'type':'scatter'}, ],
)
)
Plot: Selected button option is N
The complete code snippet below will also include an option to select all elements after you've made another selection
Complete code:
import plotly.express as px
import plotly.graph_objects as go
import pandas as pd
df = pd.DataFrame({'x':[0.12,0.11, 0.45, 0.91],
'y':[0.55, 0.89, 0.34, 0.91],
'special':['N', 'Y', 'Y', 'N']})
df
fig = go.Figure()
fig.add_traces(go.Scatter(x=df['x'], y = df['y'], mode = 'markers'))
# fig.show()
buttons = []
# button with one option for each 'special'
for s in df['special'].unique():
buttons.append(dict(method='restyle',
label=s,
visible=True,
args=[{'y':[df[df['special']==s]['y'].values],
'x':[df[df['special']==s]['x'].values],
'type':'scatter'}, ],
)
)
# add first option for all 'special'
buttons.insert(0, dict(method='restyle',
label='all',
visible=True,
args=[{'y':[df['y'].values],
'x':[df['x'].values],
'type':'scatter'}, ],))
# some adjustments to the updatemenus
updatemenu = []
your_menu = dict()
updatemenu.append(your_menu)
updatemenu[0]['buttons'] = buttons
updatemenu[0]['direction'] = 'down'
updatemenu[0]['showactive'] = True
# add dropdown menus to the figure
fig.update_layout(showlegend=False, updatemenus=updatemenu)
fig.show()
I generate daily two histograms from data, one with the needed values and the other with the reached values for different stations. I want to plot these histograms side by side, like the bottom pink example in Plotly here (see link for source code). However, since both histograms are generated daily, I need to add a time slider to the graph, like the bottom example 'Simple Slider' from Plotly (see link for source code).
My problem is that the first example uses
fig = dict(data=data, layout=layout)
plotly.offline.plot(fig, filename='Sine Wave Slider')
to plot the histogram, while for the slider the following is used:
import plotly.graph_objs as go
fig = go.Figure(data=data, layout=layout)
plotly.offline.plot(fig, filename='styled histogram')
My (not functioning) code right now is looking like this, where I try to plot the same 2 histograms 3 times. How can I change the code to generate a figure that uses both histograms (both with different random data) and the slider at the same time?
import plotly
import plotly.graph_objs as go
import numpy as np
x0 = np.random.randn(500)
x1 = np.random.randn(500)+1
trace1 = go.Histogram(
x=x0,
histnorm='count',
name='control',
autobinx=False,
xbins=dict(
start=-3.5,
end=3.0,
size=0.5
),
marker=dict(
color='#FFD7E9',
),
opacity=0.75
)
trace2 = go.Histogram(
x=x1,
name='experimental',
autobinx=False,
xbins=dict(
start=-2.0,
end=5,
size=0.5
),
marker=dict(
color='#EB89B5'
),
opacity=0.75
)
data = [trace1, trace2]
layout = go.Layout(
title='Sampled Results',
xaxis=dict(
title='Value'
),
yaxis=dict(
title='Count'
),
bargap=0.2,
bargroupgap=0.1
)
steps = []
for i in range(len(trace1)):
step = dict(
method = 'restyle',
args = ['visible', [False] * len(trace1)],
)
step['args'][1][i] = True # Toggle i'th trace to "visible"
steps.append(step)
sliders = [dict(
active = 20,
currentvalue = {"prefix": "Frequency: "},
pad = {"t": 3},
steps = steps
)]
layout = dict(sliders=sliders)
fig = dict(data=data, layout=layout)
plotly.offline.plot(fig, filename='Histogram Slider')
You could create a list of histograms, let's say 3 days (total_days = 3, odd numbers are experimental, even numbers are control).
Only the first traces are shown (visible = day < 1).
Each step in the slider shows/hides another pair of traces.
import plotly
import numpy as np
plotly.offline.init_notebook_mode()
total_days = 3
data = list()
for day in range(total_days):
data.append(plotly.graph_objs.Histogram(
x=np.random.randn(500) + day * 0.5,
histnorm='count',
name='Day {}, control'.format(day),
visible=day < 1
)
)
data.append(plotly.graph_objs.Histogram(
x=np.random.randn(500) + day,
histnorm='count',
name='Day {}, experimental'.format(day),
visible=day < 1
)
)
steps = list()
for i in range(total_days):
step = dict(
method='restyle',
args=['visible', [False] * total_days * 2],
label='Day {}'.format(i)
)
step['args'][1][i * 2] = True
step['args'][1][i * 2 + 1] = True
steps.append(step)
sliders = [dict(
active=0,
steps=steps
)]
layout = dict(sliders=sliders)
fig = dict(data=data, layout=layout)
plotly.offline.iplot(fig)