I'm new to Plotly and I'm trying to have buttons for each subplot and not the figure. I'm not able to find the way to do it or find the way for it.
Can anyone please help me how can I do it ?
Here is my code :
def plot_data(data, filename):
"""
Plotting the data
param data: data to plot.
param filename: file name to write the output in.
return: None.
"""
subplot_titles_tuple = get_titles(data)
fig = make_subplots(shared_xaxes=False,rows=len(data), cols=1, subplot_titles=subplot_titles_tuple)
for i, segment in enumerate(data):
trace = go.Scatter(x=segment['x'], y=segment['y'], mode='lines', name=f"Plot {i + 1}") # change the name of the plot
#print('im here',segment['x'] )
fig.add_trace(trace,row=i+1,col=1)
# Set subplot titles
fig.update_layout(title=f"Plots for {filename}")
# Set x-axis and y-axis titles according to segment data
x_title = segment.get('x_array_label', 'RCM') # Default to 'X-axis' if 'x_array_label' is not present
y_title = segment.get('y_array_label', 'Y-axis') # Default to 'Y-axis' if 'y_array_label' is not present
fig.update_xaxes(title_text=x_title, row=i + 1, col=1)
fig.update_yaxes(title_text=y_title, row=i + 1, col=1)
### Buttons for the user to change in the plot
fig.update_layout(
updatemenus=[
dict(
buttons=[
dict(label="Linear", method="relayout", args=[{"yaxis.type": "linear"}]),
dict(label="Log", method="relayout", args=[{"yaxis.type": "log"}]),
dict(label="Points", method="restyle", args=[{"mode": "markers"}]),
dict(label="Line", method="restyle", args=[{"mode": "lines+markers"}]),
],
direction="down",
showactive=True,
x=1,
xanchor="left",
y=0.9,
yanchor="top"
)
]
)
# change xlim and ylim
xlim_slider = widgets.FloatRangeSlider(
value=[min(segment['x']), max(segment['x'])], # Initial limits based on data
min=min(segment['x']),
max=max(segment['x']),
step=0.1,
description='xlim:',
continuous_update=False
)
ylim_slider = widgets.FloatRangeSlider(
value=[min(segment['y']), max(segment['y'])], # Initial limits based on data
min=min(segment['y']),
max=max(segment['y']),
step=0.1,
description='ylim:',
continuous_update=False
)
# Function to update xlim and ylim
def update_plot(xlim, ylim):
fig.update_xaxes(range=xlim)
fig.update_yaxes(range=ylim)
# Connect sliders to update function
widgets.interactive(update_plot, xlim=xlim_slider, ylim=ylim_slider)
# Show or save the plot
plot_filename = f"{os.path.splitext(filename)[0]}_plots.html"
plot_path = os.path.join(os.getcwd(), plot_filename)
fig.write_html(plot_path)
print(f"All plots saved in {plot_filename}")
This is what I'm getting : screenshot.
I want those options on each subplots not the whole graph.
The main issue is that
fig.update_layout(updatemenus=[...])is executed inside the for loop, and thus at each iteration theupdatemenuslist in the layout config is overridden, not extended (same problem with the layouttitle, though you can only set one title anyway since the layout config applies to the whole figure, but it seems you already managed that usingsubplot_titles).Regarding the buttons updating the yaxis type, you need to specify the axis id (eg.
yaxis,yaxis2, etc.) that corresponds to the subplot index.And for the buttons invoking the restyle method, you need to specify a list of trace indices that corresponds to the trace(s) present on the corresponding subplot (ie. trace index won't necessarily match subplot index).