Converting json to plotly graph objects to download histograms

Hi,

I trying to create a program to show histograms and be able to download them with the click of a button.
From here (bottom of the page), I understand that the data should be a plotly graph object to be an output to dcc.Download.
How can I turn json data into graph objects?
This is what I have:

import dash
from dash import dcc, html, Input, Output, State
import plotly.express as px
import pandas as pd
import json
import plotly.graph_objects as go

data = pd.DataFrame({
    'Values': [1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6, 7]
})

app = dash.Dash(__name__)

app.layout = html.Div([
    html.Button('Generate Histogram', id='generate-button', n_clicks=0),
    dcc.Graph(id='histogram'),
    html.Button('Download Histogram', id='download-button'),
    dcc.Store(id='histogram-store'),
    dcc.Download(id='image-download')
])

@app.callback(
    Output('histogram', 'figure'),
    Output('histogram-store', 'data'),
    Input('generate-button', 'n_clicks'),
    prevent_initial_call=True
)
def update_histogram(n_clicks):

    if n_clicks:    
        histogram_fig = px.histogram(data, x='Values', nbins=7)
        histogram_json = histogram_fig.to_json()
        
        return histogram_fig, histogram_json

@app.callback(
    Output('image-download', 'data'),
    Input('download-button', 'n_clicks'),
    State('histogram-store', 'data'),
    prevent_initial_call=True
)
def download(n_clicks, histogram_json):
    if n_clicks:
        graph_data = json.loads(histogram_json)

        return dcc.send_bytes(graph_data, "figure.png")

# Run the app
if __name__ == '__main__':
    app.run_server(debug=True)

Thank you for your help.

go.Figure() (line 46) does the job.

import dash
from dash import dcc, html, Input, Output, State
import plotly.express as px
import pandas as pd
import json
import plotly.graph_objects as go

data = pd.DataFrame({
    'Values': [1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6, 7]
})

app = dash.Dash(__name__)

app.layout = html.Div([
    html.Button('Generate Histogram', id='generate-button', n_clicks=0),
    dcc.Graph(id='histogram'),
    html.Button('Download Histogram', id='download-button'),
    dcc.Store(id='histogram-store'),
    dcc.Download(id='image-download')
])

@app.callback(
    Output('histogram', 'figure'),
    Output('histogram-store', 'data'),
    Input('generate-button', 'n_clicks'),
    prevent_initial_call=True
)
def update_histogram(n_clicks):

    if n_clicks:    
        histogram_fig = px.histogram(data, x='Values', nbins=7)
        histogram_json = histogram_fig.to_json()
        
        return histogram_fig, histogram_json

@app.callback(
    Output('image-download', 'data'),
    Input('download-button', 'n_clicks'),
    State('histogram-store', 'data'),
    prevent_initial_call=True
)
def download(n_clicks, histogram_json):
    if n_clicks:
        graph_data = json.loads(histogram_json)

        fig = go.Figure(graph_data)

        return dcc.send_bytes(fig.write_image, "figure.png")

# Run the app
if __name__ == '__main__':
    app.run_server(debug=True)

1 Like