I am trying to save a Dash layout in an HTML file, but I couldn’t find a way to achieve this. Strange enough it is quite easy to save a single Plotly figure, but not a Dash layout. Does anyone have a solution?
I saw this question has already an answer here https://stackoverflow.com/a/51013594/3057377, but I don’t understand it. Especially the note about the interactivity loss. One can see that interactivity is kept when saving a single plot, so it should be the same for an entire layout.
Here are the things I already tried:
import dash_core_components as dcc
import dash_html_components as html
import dash
import plotly as py
import plotly.graph_objs as go
# Create two figures.
fig1 = go.Figure(data=go.Scatter(x=[0, 1, 2], y=[0, 10, 0]))
fig2 = go.Figure(data=go.Scatter(x=[0, 1, 2], y=[0, -10, 0]))
# Write fig1 to HTML. The three methods below work.
py.io.write_html(fig1, file="fig1_a.html", auto_open=True)
fig1.write_html(file="fig1_b.html", auto_open=True)
py.offline.plot(fig1, filename='fig1_c.html', auto_open=True)
# Write fig2 to HTML. The three methods below work.
py.io.write_html(fig2, file="fig2_a.html", auto_open=True)
fig2.write_html(file="fig2_b.html", auto_open=True)
py.offline.plot(fig2, filename='fig2_c.html', auto_open=True)
# Now create a layout that will be displayed in an HTML page.
app = dash.Dash(__name__)
app.layout = html.Div([dcc.Graph(id="fig1", figure=fig1),
dcc.Graph(id="fig2", figure=fig2)])
# Trying to save the layout to HTML doesn’t work with the same three methods as above.
print("############ 1")
try:
py.io.write_html(app.layout, file="app_layout_a.html", auto_open=True)
except Exception as e:
print(e)
print("############ 2")
try:
app.layout.write_html(file="app_layout_c.html", auto_open=True)
except Exception as e:
print(e)
print("############ 3")
try:
py.offline.plot(app.layout, filename='app_layout_b.html')
except Exception as e:
print(e)
# But the layout displays correctly when served by Dash.
app.run_server(debug=True)
You can save the HTML code that contains the graph's information into a variable. In order to plot the graph, you can use html.Iframe
from dash_html_components
. If the graph is generated inside a Dash callback you can return that variable or the Iframe as the output of the callback.
I also share how I save plotly figures to HTML. The plot remains interactive and the HTML file is considerably lighter than other alternatives (like fig.write_html()
).
with open('plot.html', 'w') as f:
f.write(fig.to_html(full_html=False, include_plotlyjs='cdn'))
Here is a minimum working example in a Dash application. In this case, the figure is in a callback because each time you click in the bottom "Rotate" the figure is updated and rotates the tick labels. This app is a modification from the Plotly Docs:
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.express as px
df = px.data.tips()
app = dash.Dash(__name__)
app.layout = html.Div([
html.Button("Rotate", id='button', n_clicks=0),
html.Div(id="output", children=[])
])
@app.callback(
Output('output', 'children'), # The output will be displayed in html.Div(id="output)
[Input("button", "n_clicks")])
def rotate_figure(n_clicks):
fig = px.histogram(df, x="sex", height=500)
fig.update_xaxes(tickangle=n_clicks*45)
# The plotly figure is saved as HTML in a variable
html_data = fig.to_html(full_html=False, include_plotlyjs='cdn')
# The variable is then displayed as a plot using Iframe from dash_html_components
html_plot = html.Iframe(srcDoc = html_data,
style = {"height": "1000px",
"width": "1000px",
"display":"flex",
"align-items": "center",
"justify-content": "center"}
)
# Now you can return the Iframe as a children of a Div
return html_plot
app.run_server(debug=True)
Simply use the following command:
fig.write_html("path/to/file.html")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With