Scattergeo Plots Offline?

Hello,

This is my first post, Iā€™m not sure of the format of topics on this site just yet.

Iā€™m working in a completely offline environment utilizing Plotly with Python to make some plots. I have come across an issue regarding Map Plots. I have made a Scattergeo plot and the figure never seems to render.

Hereā€™s some example code:

import plotly
import plotly.graph_objects as go
import numpy as np
import pandas as pd
from plotly.offline import plot

fig = go.Figure()
size = 50
#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
                    )
                )
)
plot(fig)

Whenever I run this code, the figure attempts to pop up in a browser, but the figure never renders. I have noticed that there are references to ā€œhttp://www.w3.orgā€ in the HTML. Is there a way to make these plots with complete offline support?

If scattergeo is not the way to go, then is there another plot that I can do to achieve the same result?

I have tried to create other plot types, and they seem to work fine.

Any suggestions would be greatly appreciated.

Hi @carlmarl,

Welcome to Plotly forum!! What Plotly version are you running?
With the last one (4.8.1) your code works.

scatter-geo

Hi empet,

I am using version 4.7.1. It is the latest version included in Anaconda afaik. Do you believe that this would cause issue? Also, is there any way to make plotly get rid of any external references in the HTML?

@carlmarl
There is no reason to not work with 4.7.1.

It still does not seem to work. Is there any way to get those links that are in the html code to point to local svgs?

I guess I should caveat this by saying that the colorbar and title render, but the map itself does not.

Iā€™m able to recreate what I see on our network on a network with a connection. It has to do with the topojsonURL in the config.

If you do the following plot call, you will see what I see.

plot(fig,config={'topojsonURL':'some_unreachable_URL'})

So, I have found some posts related to my issue, but Iā€™m unable to understand them.

Here is the first Link.

So, I have saved the json file that is hosted on cdn.plot.ly/world_110m.json to a local directory, for examples sake say I saved it in C:\MyJson\world_110m.json .

In that post the reply states that the file might need to hosted on a server, so I host the directory C:\MyJson on port 8000 so that I can view the json at 127.0.0.1/world_110m.json and do

I used the following command to setup the simple http server:

python -m SimpleHTTPServer 8000

inside the C:\MyJson directory.

plot(fig,config={'topojsonURL':'127.0.0.1:8000'})

I have also tried

plot(fig,config={'topojsonURL':'127.0.0.1:8000/world_110m.json'})

but neither of these work. Now that Iā€™ve learned that there is a topojsonURL in the HTML, Iā€™ve noticed too that there is a topojsonName, however, I do not see the ā€˜world_110m.jsonā€™ set to any variable.

I have tried to add ā€˜topojsonNameā€™ in the config dictionary, however, there isnā€™t an option to do that. It doesnā€™t seem to exist in the config: here

I cannot seem to change the topojsonName, is there any way to do that in python? Also, am I on the right track to getting this to work?

EDIT:

I have the python simple server setup like above, and it is outputting the following:

127.0.0.1 - - [08/Jun/2020 15:20:12] ā€œGET /world_110m.json HTTP/1.1ā€ 200 -

which seems like it is requesting the correct file, however, the plot is still not renderingā€¦ Iā€™m lost.

Bump.

I still havenā€™t found any way to make any progress.

I have figured out the issue. Turns out that the python simple HTTP server will not work because there is a cross origin issue. Best to serve the world_{resolution}.json files using Flask and returning a JSON.dumps of the file. This will make the plots work.

Hello,
i run my code on a JupyterHub server on which i cannot setup a new server to serve world_110m.json file.
Is there a way to set a path to the file ?
Something like that ?

fig = go.Figure(go.Scattergeo())
fig.update_geos(projection_type="orthographic")
fig.update_layout(height=300, margin={"r":0,"t":0,"l":0,"b":0})
fig.show(config={'topojsonURL':'/home/user/'})

Regards

@carlmarl - Iā€™m trying your example above and have another server running NGINX serving up the *.json files in
a folder named /var/www/html/assets on port 80 as follows: plot(fig,config={ā€˜topojsonURLā€™:ā€˜xx.xx.xx.xx:80/assetsā€™}) and have also tried plot(fig,config={ā€˜topojsonURLā€™:ā€˜xx.xx.xx.xx:80/assets/world_110m.jsonā€™}) but I donā€™t see any activity on /var/log/nginx/access.log.

If I hit the same URL (e.g., ā€˜xx.xx.xx.xx:80/assets/world_110m.jsonā€™) from my browser I get the JSON code back and see the status 200 in my NGINX log.

Iā€™m a full stack Python Flask developer but am not sure exactly how you got it working with Flask with regards to the example code above in your initial post. Could you provide some additional details please?

Here is my entire test_offline_cdn3.py file with the IP address redacted with xx.xx.xx.xx.

Thanks!

-Tim

import plotly
import plotly.graph_objects as go
import numpy as np
import pandas as pd
from plotly.offline import plot

fig = go.Figure()
size = 50
#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
)
)
)
plot(fig,config={ā€˜topojsonURLā€™:ā€˜xx.xx.xx.xx:80/assetsā€™})