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:
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()
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()
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:
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
How to Avoid Last Comma in Python Loop
Python: Pickle.Load() Raising Eoferror
Python: How to Calculate the Sum of Numbers from a File
How to Iterate Through Cur.Fetchall() in Python
Python-Compare Two String Columns in Same Dataframe, Return Matching Result
What Is the Most Efficient Way to Sum a Dict With Multiple Keys by One Key
Python Not Working in the Command Line of Git Bash
Iterating Over Every Two Elements in a List
Formal and Actual Parameters in a Function in Python
Pandas - Drop Last Column of Dataframe
Conversion of String to Upper Case Without Inbuilt Methods
Discord.Py Show Who Invited a User
How to Do This Horizontally Instead of Vertically in Python
How to Add Thousand Separator to Numbers in Python Pandas Dataframe
Asking the User for Input Until They Give a Valid Response
How to Send Smtp Email for Office365 With Python Using Tls/Ssl
Python/Pandas: How to Match List of Strings With a Dataframe Column