Plotly: Plot Multiple Figures as Subplots

Plotly: Plot multiple figures as subplots

You can get a dashboard that contains several charts with legends next to each one:

import plotly
import plotly.offline as py
import plotly.graph_objs as go
fichier_html_graphs=open("DASHBOARD.html",'w')
fichier_html_graphs.write("<html><head></head><body>"+"\n")

i=0
while 1:
if i<=40:
i=i+1


#______________________________--Plotly--______________________________________


color1 = '#00bfff'
color2 = '#ff4000'

trace1 = go.Bar(
x = ['2017-09-25','2017-09-26','2017-09-27','2017-09-28','2017-09-29','2017-09-30','2017-10-01'],
y = [25,100,20,7,38,170,200],
name='Debit',
marker=dict(
color=color1
)

)
trace2 = go.Scatter(

x=['2017-09-25','2017-09-26','2017-09-27','2017-09-28','2017-09-29','2017-09-30','2017-10-01'],
y = [3,50,20,7,38,60,100],
name='Taux',
yaxis='y2'

)
data = [trace1, trace2]
layout = go.Layout(
title= ('Chart Number: '+str(i)),
titlefont=dict(
family='Courier New, monospace',
size=15,
color='#7f7f7f'
),
paper_bgcolor='rgba(0,0,0,0)',
plot_bgcolor='rgba(0,0,0,0)',

yaxis=dict(
title='Bandwidth Mbit/s',
titlefont=dict(
color=color1
),
tickfont=dict(
color=color1
)
),
yaxis2=dict(
title='Ratio %',
overlaying='y',
side='right',
titlefont=dict(
color=color2
),
tickfont=dict(
color=color2
)

)

)
fig = go.Figure(data=data, layout=layout)
plotly.offline.plot(fig, filename='Chart_'+str(i)+'.html',auto_open=False)
fichier_html_graphs.write(" <object data=\""+'Chart_'+str(i)+'.html'+"\" width=\"650\" height=\"500\"></object>"+"\n")
else:
break


fichier_html_graphs.write("</body></html>")
print("CHECK YOUR DASHBOARD.html In the current directory")

Result:

enter image description here

Plotly: Add figures with multiple subplots to one single figure

  • focus on the detail of the axis layouts and you can make one sub-plots chart
  • for this case only two settings need to be modified - see below
sub_fig3 = make_subplots(rows=2, cols=2, shared_xaxes=True, vertical_spacing=0.02)

sub_fig3 = sub_fig3.add_trace(sub_fig1.data[0], row=1, col=1)
sub_fig3 = sub_fig3.add_trace(sub_fig1.data[1], row=2, col=1)
sub_fig3 = sub_fig3.add_trace(sub_fig2.data[0], row=1,col=2)
sub_fig3 = sub_fig3.add_trace(sub_fig2.data[1], row=2,col=2)


sub_fig3 = sub_fig3.update_layout(
xaxis_rangeslider_visible=False,
xaxis3={"anchor": "y3"},
xaxis2_rangeslider_visible=False,
)
sub_fig3.show()

Sample Image

Multiple plotly plots on 1 page without subplot

So, in conclusion, I have not found a way to do this purely with plotly. Below is my code for doing this with Dash, which has been working quite well:

Step 1: make a few plotly plots

import plotly.offline as pyo
import plotly.graph_objs as go
import plotly as py
fig1 = go.Scatter(y=[1,2,3])
fig2 = go.Scatter(y=[3,2,1])
plots = [fig1, fig2]

Step 2: Make dash Div objects:

app = dash.Dash()
layout = html.Div(
[html.Div(plots[i]) for i in range(len(plots))],
style = {'margin-right': '0px'}
)

Step 3: Run dash

app.layout = layout
app.run_server(port=8052)

Display multiple plots (not subplots) with plotly

To add a legend to each of the subplots, give the legend group a string in group units. They are usually arranged according to each subplot. In your example, you will need to adjust the spacing between the legends because of the large number of graphs. I found the current values through trial and error.

fig = make_subplots(rows=len(Regiones),
cols=1,
subplot_titles=Regiones)

for i,r in enumerate(Regiones):
target_regions = df.query('Region == @r').drop('Region', axis=1).set_index('Serie').T
for c in target_regions.columns[:3]:
fig = fig.add_trace(
go.Scatter(x=target_regions.index,
y=target_regions[c],
name=c,
mode='lines',
legendgroup=str(i),
showlegend=True
), row=i+1, col=1)

fig.update_layout(title={'text':f'Camas UCI por región', 'x':.45},
template='plotly_white', hovermode='x',
showlegend=True,
xaxis_title="Días",
yaxis_title="Cantidad de camas",
legend_tracegroupgap=90,
height=2600
)

fig.add_annotation(x=0.75, y=0.00,
text = 'Fuente: Datos obtenidos desde el Ministerio de Ciencia:',
showarrow = False,
xref='paper',
yref='paper',
xanchor='right',
yanchor='bottom',
xshift=0,
yshift=-30
)


fig.show()

Sample Image

Subplot for Go.Figure objects with multiple plots within them

It's a simple case of loop over traces in each of the figures and add them to required sub-plot.

# Data Visualization
from plotly.subplots import make_subplots
import plotly.graph_objects as go

epoch_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
loss_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
val_loss_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
error_rate = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
val_error_rate = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

loss_plots = [go.Scatter(x=epoch_list,
y=loss_list,
mode='lines',
name='Loss',
line=dict(width=4)),
go.Scatter(x=epoch_list,
y=val_loss_list,
mode='lines',
name='Validation Loss',
line=dict(width=4))]

loss_figure = go.Figure(data=loss_plots)

error_plots = [go.Scatter(x=epoch_list,
y=loss_list,
mode='lines',
name='Error Rate',
line=dict(width=4)),
go.Scatter(x=epoch_list,
y=val_loss_list,
mode='lines',
name='Validation Error Rate',
line=dict(width=4))]

error_figure = go.Figure(data=error_plots)

metric_figure = make_subplots(
rows=3, cols=2,
specs=[[{}, {}],
[{}, {}],
[{'colspan': 2}, {}]])

for t in loss_figure.data:
metric_figure.append_trace(t, row=1, col=1)
for t in error_figure.data:
metric_figure.append_trace(t, row=1, col=2)
metric_figure.show()

Is there a way to use Plotly express to show multiple subplots

For a plotly express solution:

You could use pd.melt() to get all your variables in the same column:

import pandas as pd
import plotly.express as px

df = pd.DataFrame({
'Day':range(10),
'Temperature': np.random.rand(10),
'Wind': np.random.rand(10),
'Humidity': np.random.rand(10),
'Pressure': np.random.rand(10),})

df_melt = df.melt(
id_vars='Day',
value_vars=['Temperature', 'Wind', 'Humidity', 'Pressure'])

Your dataframe now looks like this with the variable names in a column named 'variable' and the values in a column named 'value':

    Day variable    value
0 0 Temperature 0.609
1 1 Temperature 0.410
2 2 Temperature 0.194
3 3 Temperature 0.663
4 4 Temperature 0.351

Now you can use px.scatter() with argument facet_col to get the multiple plots:

fig = px.scatter(
df_melt,
x='Day',
y='value',
facet_col='variable',
facet_col_wrap=2,
color='variable',
width=800,
)

This results in the following plot:
plotly express facet_col instead of subplots

Now in your example all variables have the same range of values. But if this is not the case then you might want to make sure that every plot gets its own range on the y-axis. This can be done as follows:

fig.update_yaxes(showticklabels=True, matches=None)

More info on facet plots can be found here:

https://plotly.com/python/facet-plots/

Plotly saving multiple plots into a single html

In the Plotly API there is a function to_html which returns HTML of the figure. Moreover, you can set option param full_html=False which will give you just DIV containing figure.

You can just write multiple figures to one HTML by appending DIVs containing figures:

with open('p_graph.html', 'a') as f:
f.write(fig1.to_html(full_html=False, include_plotlyjs='cdn'))
f.write(fig2.to_html(full_html=False, include_plotlyjs='cdn'))
f.write(fig3.to_html(full_html=False, include_plotlyjs='cdn'))

https://plot.ly/python-api-reference/generated/plotly.io.to_html.html

You can also use Beautiful Soup to do DOM manipulation and insert DIV exactly where you need it in the HTML.

https://beautiful-soup-4.readthedocs.io/en/latest/#append



Related Topics



Leave a reply



Submit