plotly / Kaleido

Fast static image export for web-based visualization libraries with zero dependencies
MIT License
378 stars 38 forks source link

Can't generate Choropleths behind proxy #107

Closed Guiraiol closed 4 months ago

Guiraiol commented 3 years ago

I'm trying to export a static choropleth but I can't get through some topojsons. I'll use Choropleth map using GeoJSON as an example.

Enviroment

Docker image centos8:latest Python 3.8.10 from miniconda (https://repo.anaconda.com/miniconda/Miniconda3-py38_4.10.3-Linux-x86_64.sh) pip 21.2.4 plotly==5.2.1 plotly-geo==1.0.0 kaleido==0.2.1

My proxy is set at HTTPS_PROXY, HTTP_PROXY, https_proxy and http_proxy and pandas and urlopen at the example can access the URLs, but plotly/kaleido can't.

Code

from urllib.request import urlopen
import json
with urlopen('https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json') as response:
    counties = json.load(response)

import pandas as pd
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/fips-unemp-16.csv",
                   dtype={"fips": str})

import plotly.express as px

fig = px.choropleth(df, geojson=counties, locations='fips', color='unemp',
                           color_continuous_scale="Viridis",
                           range_color=(0, 12),
                           scope="usa",
                           labels={'unemp':'unemployment rate'}
                          )
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.to_image("png")

And it raises this error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/root/miniconda/lib/python3.8/site-packages/plotly/basedatatypes.py", line 3758, in to_image
    return pio.to_image(self, *args, **kwargs)
  File "/root/miniconda/lib/python3.8/site-packages/plotly/io/_kaleido.py", line 145, in to_image
    img_bytes = scope.transform(
  File "/root/miniconda/lib/python3.8/site-packages/kaleido/scopes/plotly.py", line 161, in transform
    raise ValueError(
ValueError: Transform failed with error code 525: unexpected error while fetching topojson file at https://cdn.plot.ly/usa_110m.json

I tried to download this file and provide locally using a scope:

import plotly.io as pio
pio.kaleido.scope.topojson = "/home/usa_110m.json"

and

from kaleido.scopes.plotly import PlotlyScope

scope = PlotlyScope(
    topojson="/home/usa_110m.json")

But both ways raise this error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/root/miniconda/lib/python3.8/site-packages/plotly/basedatatypes.py", line 3758, in to_image
    return pio.to_image(self, *args, **kwargs)
  File "/root/miniconda/lib/python3.8/site-packages/plotly/io/_kaleido.py", line 145, in to_image
    img_bytes = scope.transform(
  File "/root/miniconda/lib/python3.8/site-packages/kaleido/scopes/plotly.py", line 153, in transform
    response = self._perform_transform(
  File "/root/miniconda/lib/python3.8/site-packages/kaleido/scopes/base.py", line 293, in _perform_transform
    self._ensure_kaleido()
  File "/root/miniconda/lib/python3.8/site-packages/kaleido/scopes/base.py", line 203, in _ensure_kaleido
    raise ValueError(startup_response.get("message", "Failed to start Kaleido subprocess"))
ValueError: --topojson argument is not a valid URL: /home/usa_110m.json

So, there's a way to provide these topojsons offline, or a way to configure kaleido proxy?

jonmmease commented 3 years ago

Hi @Guiraiol , try using a file uri for the file. e.g. file:///home/usa_110m.json. (note there are three forward slashes. The first two are for the file uri, the third is for the filesystem root).

Guiraiol commented 3 years ago

Thank you for your prompt reply @jonmmease. That worked perfectly. I tried to use this with two slashes and I assumed that that wasn't the way. I just want to ask if you can update the documentation to add this at Low-level Kaleido Scope Developer API, because the given example for plotlyjs use a local path.

jonmmease commented 3 years ago

Great! I added the documentation tag to remind us to come back to this. The semi-tricky thing is that for implementation reasons, using a local path (without the file uri) is fine for plotlyjs.

gvwilson commented 4 months ago

Thanks for your interest in Kaleido. We are currently working on an overhaul that might address your issue - we hope to have news in a few weeks and will post an update then. Thanks - @gvwilson