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)
Related
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()
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)
In case of 2d charts in plotly we can set standoff of axis label by setting standoff property (example: https://community.plotly.com/t/adding-space-beetween-axis-title-and-values/32218), but in case of 3d plots there is no property standoff because axis have to specified as dictionary values of scene, the problem is custom ticks labels overlap with axis label:
import plotly.graph_objects as go
import numpy as np
ticktext = ["tick labels X"] * 3
layout = go.Layout(
scene = dict(
xaxis = dict(
title=dict(text='xaxis'
#, standoff=20 # don't work
),
tickvals=list(range(len(ticktext))),
ticktext=ticktext,
),
yaxis = dict(
title='yaxis',
tickvals=list(range(len(ticktext))),
ticktext=ticktext,
),
zaxis = dict(
title='zaxis',
)
),
)
# chart
data = np.array([[1,2,3],[3,1,2],[3,1,2]])
plotly_input_data = []
plotly_input_data.append(go.Surface(z = data + 1, showscale=False, opacity=0.9))
plotly_input_data.append(go.Surface(z = data**2-6, showscale=False, opacity=1.0))
fig = go.Figure(data=plotly_input_data, layout = layout)
fig.show()
This is '4.13.0' version of plotly.
Edition
Also using fig.layout.xaxis.title.standoff = 20 does not work.
Hi I am having trouble getting a lineplot to display properly. I have two axes and 5 line plots on one figure. The first y-axis limit cannot be set. I tried setting the range property to [0,2], however it doesn't do anything and continues to show from -2 to 4. I want the straight linear plot to overlay directly on top of the other 4 line plots and I don't know why the x-axis starts from -5. Can someone help fix the issue?
fig = go.Figure()
xs = np.linspace(0,12.5,plot_df.shape[0])
for cn in plot_df.columns:
ys = plot_df[cn].to_numpy()
fig.add_trace(go.Scatter(x=xs, y=ys,
mode='lines',
name=cn)
)
fig.add_trace(go.Scatter(x=xs, y=xs,
mode='lines',
name='mob. grad', yaxis="y2")
)
fig.update_layout(
title = "UV and Mobile phase trace of {}".format(field_dict['sample_name']),
xaxis = dict(
title = "Minutes",
domain=[0.2, 1]
),
yaxis = dict(
scaleanchor = "x",
title = "UV Abs",
range = [0,2],
position = 0.19
),
yaxis2 = dict(
title = "Mobile Phase (%)",
anchor="free",
domain=[0.1,1],
overlaying="y",
side="left",
position=0.08,
range=[0,100])
)
fig.show()
I just removed scaleanchor = "x" and it showed up properly.
I am having an issue with graph resizing due to legends when using pyplot. This is the code:
random_x = df['column1']
random_y = df['column2']
random_x1 = df['column1']
random_y1 = df['column3']
trace = go.Scatter(
x = random_x,
y = random_y,
name='abcdefghijklmnop......'
)
trace1 = go.Scatter(
x = random_x1,
y = random_y1,
name='abcdefghijklmnopadfdsfsdff......'
)
data = [trace,trace1]
iplot(data, filename='basic-line')
It gives me the graph but since my legend characters are long, it reduces the size of my actual graph. I want the legends to either come at the bottom or go further to the top
layout = go.Layout(
legend=dict(
orientation="h")
)
figure=go.Figure(data=data, layout=layout)
iplot(figure,filename='basic-line')