1

I have seen similar questions up before without answer.

The aim is to show the image on the Flask application but with the altered config.

How is the config setting on Plotly charts altered when converting the graph into JSON and not using the fig.show()? If the fig.show() was used then the config would be amended inside there.

Flask Code:

Of course, if this was just to show the graph fig.show would be used but this is passing it through to JSON.

#example flask application with graph
from flask import Flask, render_template, request
import plotly.express as px
import plotly
import numpy as np
import json

#Flask settings.
secret_key = 'verysecretkey123lol' #secret key
app = Flask(__name__)

#simple image
img_rgb = np.array([[[255, 0, 0], [0, 255, 0], [0, 0, 255]],
                    [[0, 255, 0], [0, 0, 255], [255, 0, 0]]
                   ], dtype=np.uint8)
fig = px.imshow(img_rgb)

#Flask
@app.route("/", methods=['GET', 'POST'])
def create():
    image = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)

    return render_template('example.html', image = image)

#Run
if __name__ == "__main__":
    app.secret_key = secret_key
    app.run(debug = False)

HTML Code (example.html):

I have added the Config as a javascript variable below.

<!DOCTYPE html>
<html>

  <head lang="en">
    <title>Dissertation</title>
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>

  <body>
    <div class="chart" id="image">
      <script>
        var graphs = {{image | safe}};
        var config = {"displaylogo": FALSE, 'modeBarButtonsToAdd': ['drawclosedpath', 'eraseshape']};
        Plotly.plot('image', graphs, {});
      </script>
    </div>
  </body>

</html>

Any help would be greatly appreciated, thanks

Andrew

Andrew
  • 43
  • 5

3 Answers3

6

I struggled with trying to pass config options to Plotly when embedding the plots in a Flask application. In particular, I wanted to remove modebar buttons in my application. I discovered the way to achieve this from this related question.

Specifically, in the HTML code where you call the JS to display the plot, you set the plot config using the command Plotly.setPlotConfig().

Using your code example, you can set the config and display the plot with

<body>
  <div class="chart" id="image">
    <script>
      var graphs = {{image | safe}};
      var config = {"displaylogo": FALSE, 'modeBarButtonsToAdd': ['drawclosedpath', 'eraseshape']};

      Plotly.setPlotConfig(config);
      Plotly.plot('image', graphs, {});
    </script>
  </div>
</body>
stephenjmaher
  • 61
  • 1
  • 2
0

If you have already included some config file in the HTML by using Plotly.setPlotConfig(config); and use Plotly.newPlot("image", graphs) to reload data, it won't work again. You must embed the config in your graphs object

//... your ajax call
     graphs.config = {'displayModeBar': false}
     Plotly.newPlot('image', graphs);
//... your ajax call
Lokinou
  • 1,039
  • 10
  • 13
0

You can get this to work for layout options and config options without any hacky extra code in the HTML. The key is remembering what render_template accepts as parameters (valid json).

  1. Convert the image, layout, and config dictionaries to json. Your "image" here could also be a "graph_object" or "figure".
image = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
layout = json.dumps({'margin': dict(l=0, r=0, t=50, b=0)})
config = json.dumps({'displaylogo': False, 'modeBarButtonsToAdd': ['drawclosedpath', 'eraseshape']}) 
  1. Pass those to render_template.
return render_template('example.html', image=image, layout=layout, config=config)
  1. Use all three in your html template, following the safe convention if you trust the data.
<script>
Plotly.newPlot('image', {{ image | safe }}, {{ layout | safe }}, {{ config | safe }});
</script>

Put that all together, and your final code would look like this

@app.route("/", methods=['GET', 'POST'])
def create():
    image = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
    layout = json.dumps({'margin': dict(l=0, r=0, t=50, b=0)})
    config = json.dumps({'displaylogo': False, 'modeBarButtonsToAdd': ['drawclosedpath', 'eraseshape']})
    return render_template('example.html', image=image, layout=layout, config=config)
<body>
  <div class="chart" id="image">
    <script>
      Plotly.newPlot('image', {{ image | safe }}, {{ layout | safe }}, {{ config | 
safe }});
    </script>
  </div>
</body>

That's it! No need to set the config/layout somewhere other than the place where you set your figure.

szofar
  • 11
  • 5