Search code examples
javascriptpythonflaskplotly

Flask Plotly Responsive in Browser


How to make this plotly chart responsive in index.html - I create a flask app and js function for rendering the plot, however, I cannot figure out, how to make it responsive. What is wrong with variable config - it seems not to work.

Thank you

Flask:

@app.route('/')
def index():

    locations = sorted(df['location'].unique())
    rooms = sorted(df['rooms'].unique())

    # Visualisation
    import json
    import plotly
    import plotly.express as px
    df.rooms = df.rooms.astype(str)
    fig = px.scatter(df, x="m2", y="price", trendline="ols", color="rooms", symbol='rooms',
                                marginal_x="histogram", 
                                marginal_y="rug",
                                template='plotly_dark', hover_data=['price', 'rooms', 'm2', 'location'],
                                title="Real Estate in Vienna")
    
    graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)

    return render_template('index.html', locations=locations, rooms=rooms, graphJSON=graphJSON)

JavaScript:

                    <!-- Visualisation -->
                    {%block content%}
                    <div class="card mb-4 m-auto" style="width: 90%">
                        <div class="card-body">
                            <div id="chart"></div>
                        </div>
                    </div>
                    {% endblock %}

    <!-- Plotly -->
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    <script type="text/javascript">
        var graphs = {{ graphJSON | safe}};
        var config = {responsive: true};
        Plotly.newPlot("chart", graphs, {}, config);
    </script>


Solution

  • I think you are using Plotly.newPlot() wrong. By reading the API reference you will see, that there are to different signatures for this function:

    1. Plotly.newPlot(graphDiv, data, layout, config)
    2. Plotly.newPlot(graphDiv, obj)

    Looks you were mixing both up since the Python function

    graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)

    returns a single object with keys for data, layout, config and frames with defaults to {data: [], layout: {}, config: {}, frames: []}.

    Thus everything should work if you use the following JavaScript that extracts the parameters data and layout from the object charts and then use

    Plotly.newPlot(graphDiv, data, layout, config)

    instead of

    Plotly.newPlot(graphDiv, obj):

    <!-- Plotly -->
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    <script type="text/javascript">
        var chart = {{graphJSON | safe}};
        var data = chart["data"];
        var layout = chart["layout"];
        var config = {responsive: true};
        Plotly.newPlot("chart", data, layout, config);
    </script>