简体   繁体   中英

How to use Plotly in offline mode?

After being fed up with Matplotlib, I'm looking into using Plotly. I have a simple plot made, however, whenever I try to create the plot the browser opens up and it is looking for "cdn cloudflare" or something like that. It hangs here for about a minute before finally showing some plots. Some plots don't even render such as the Scattergeo. Any idea on how to strip these dependencies? I'm working on a network that has no outside connection.

Note: This is test code. Change the if False to if True to run that portion of the code. I'm also using Plotly version 4.7.1

Here's some example code.

import plotly
import plotly.graph_objects as go
import plotly.io as pio
import numpy as np
import pandas as pd
pio.renderers.default = "browser"

size = 100
#Stacked Plot
if False:
    fig = go.Figure()

    #Data Creation
    y1 = np.random.randint(0,50,size)
    y2 = 50 - np.random.randint(0,25,size)
    y3 = 100 - (y2+y1)
    x = np.linspace(0,100,size)

    #Plot Essentials
    g = [go.Scatter(x=x,y=y1,mode='lines+markers',stackgroup='1',name='money'),
              go.Scatter(x=x,y=y2,mode='lines+markers',stackgroup='1',name='credit'),
              go.Scatter(x=x,y=y3,mode='lines+markers',stackgroup='1',name='IOU')]

    for s in g:
        fig.add_trace(s)
    fig.update_layout(title=dict(text='Resource Plot'),
                          xaxis = dict(title = dict(text='Time (s)')),
                          yaxis = dict(title = dict(text='Resources Used (%)'),
                                        ticksuffix = '%'))
    pio.show(fig)



### Scatter Map Plot

if False:
    fig = go.Figure()

    #Data Creation
    d = {'Lat':np.random.randint(90,120,size),
     'Lon':np.random.randint(-180,180,size),
     'colorcode':np.random.randint(-40,20,size)}
    df = pd.DataFrame(d)

    fig.add_trace(go.Scattergeo(mode = "markers+lines",lon = df['Lon'],lat = df['Lat'],marker = {'size': 10,'color':df['colorcode'],'colorscale':'jet','colorbar_thickness':20}))
    fig.update_layout(  geo = dict(
                        showland = True,
                        showcountries = True,
                        showocean = True,
                        countrywidth = 0.5,
                        landcolor = 'rgb(230, 145, 56)',
                        lakecolor = 'rgb(0, 255, 255)',
                        oceancolor = 'rgb(0, 255, 255)',
                        projection = dict(
                            type = 'orthographic',
                        ),
                        lonaxis = dict(
                            showgrid = True,
                            gridcolor = 'rgb(102, 102, 102)',
                            gridwidth = 0.5
                        ),
                        lataxis = dict(
                            showgrid = True,
                            gridcolor = 'rgb(102, 102, 102)',
                            gridwidth = 0.5
                        )
                    )
    )
    pio.show(fig)

Edit: I intend to render these plots in a QWebEngine that will be embedded inside our PyQt5 GUIs for analysis. It is okay if I can get them to render inside a web browser for now, since we have access to Firefox, granted no internet connection.

EDIT: Semi working answer. from plotly.offline import plot

plot(fig) works for some plots. But I still have issues with Scattergeo plots as in the html it still references www.w3.org. Any suggestions for map plots?

The most popular way to make charts in offline mode is to use plotly's iplot function, here's an example;

from plotly.offline import iplot, init_notebook_mode
from plotly.subplots import make_subplots
init_notebook_mode()
import plotly.graph_objs as go

trace = go.Scatter(
    x=aList,
    y=aDiffList,
    name=a_name,
    mode='markers',
    marker={'color' : 'rgb(0, 0, 0)', 'size' : 6}
)
data = [trace]
layout = {'title' : 
          {'text' : '<b>Title in Bold'}, 'x' : .5,
          'font' : {'size' : 24, 'family' : 'Raleway'}
         }
iplot({'data' : data, 'layout' : layout})

I think using iplot will make your code work

Here is the way to get this working with Maps and everything.

Create a Flask app.

import os
import sys
from flask import Flask
from flask_cors import CORS,cross_origin
import json
import argparse
from flask import session, redirect, url_for, render_template, request


app = Flask(__name__,template_folder='templates')
CORS(app)
file_dir = os.path.dirname(os.path.realpath(__file__))
    
@app.route('/plotlygeojsonfile/<path:relative_path>',methods=['GET','POST'])
@cross_origin()
def get_topojson(relative_path):
    i = json.load(open(os.path.join(file_dir,relative_path),'r'))
    return json.dumps(i)


if __name__ == "__main__":
    my_parser = argparse.ArgumentParser()
    my_parser.version = '0.1.0'
    my_parser.add_argument('-port',default=5000)
    my_parser.add_argument('-host',default='127.0.0.1')
    args = my_parser.parse_args()
    port = args.port
    host = args.host
    app.run(debug = True, port=port, host=host)

This should be inside a Flask folder [mine is named Flask].

In the directory Flask/plotly/topojson you need place the downloaded version of the usa_50m.json, usa_110m.json, world_50mjson, and world110m.json from http://cdn.plot.ly/{json file here} for each of the topojson files listed earlier in this sentence. Just navigate to the page and SAVE the json in that Flask/plotly/topojson folder.

Whenever you do a plotly.offline.plot(figure,config=config) call, your configure dictionary needs to at least include the following.

config = {'topojsonURL':f'http://{hostname}:{port}/plotlygeojsonfile/plotly/topojson/'}

where hostname is the hostname of the machine that the Flask app is running on and port is the port that the flask app is using.

This works for me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM