Search code examples
pythonplotlyvisualization

How do I save go.Choropleth's output as an image with transparent background?


I have a code that creates a map of congressional districts of Texas using go.Choropleth, with a custom GeoJson provided. It generates an image that is accessible through Plotly's web interface, but I want to save it as a .png file with custom resolution and transparent background.

import typing as t
import plotly.graph_objects as go
import pandas as pd
import json
JSON = t.Union[str, int, float, bool, None,
               t.Mapping[str, 'JSON'], t.List['JSON']]


def draw_map(districts: JSON,
             df: pd.DataFrame,
             name: str) -> None:
    colorscale = [[0, '#D40000'],
                 [0.05789804908747634, '#D40000'],
                 [0.11705475141598479, '#CC2F4A'],
                 [0.12146003775959714, '#CC2F4A'],
                 [0.13089993706733785, '#E27F90'],
                 [0.18628067967275005, '#E27F90'],
                 [0.18753933291378216, '#F2B3BE'],
                 [0.18753933291378216, '#F2B3BE'],
                 [0.8193832599118943, '#86B6F2'],
                 [0.8445563247325362, '#86B6F2'],
                 [0.9030837004405287, '#4389E3'],
                 [0.9282567652611706, '#4389E3'],
                 [0.9616110761485211, '#1666CB'],
                 [1.0, '#1666CB']]
    fig = go.Figure(data=go.Choropleth(
        geojson=districts,
        locations=df["District"],
        z=df["Result"],
        colorscale=colorscale,
        showscale=False))
    fig.update_traces(marker_line_color="white",
                      marker_line_width=1)
    fig.update_geos(fitbounds="locations",
                    projection_type="natural earth",
                    visible=False,
                    bgcolor="rgba(0,0,0,0)")
    # doesn't actually make the background transparent
    fig.update_layout(width=1000,
                      height=1000)
    fig.write_image(name)
    return fig


def main() -> None:
    with open("districts.json") as file:
        districts = json.load(file)
    #"type": "FeatureCollection",
    #"features": [
    #    {
    #        "type": "Feature",
    #        "geometry": {
    #            "type": "Polygon",
    #            "coordinates": [...
    #            ]
    #        },
    #        "properties": {
    #            "STATEFP": "12",
    #            "CD116FP": "17",
    #            "AFFGEOID": "5001600US1217",
    #            "GEOID": "1217",
    #            "NAMELSAD": "Congressional District 17",
    #            "LSAD": "C2",
    #            "CDSESSN": "116",
    #            "ALAND": 14436344131,
    #            "AWATER": 2517038161
    #        },
    #        "id": "FL-17"
    #    },
    df = pd.read_csv("texas.csv", index_col=0)
    #      Donald Trump  Joe Biden District  Result    Color State
    #TX-1          71.6       27.2     TX-1   -71.6  #D40000    TX
    #TX-2          50.9       48.6     TX-2   -50.9  #E27F90    TX
    fig = draw_map(districts, df, "TX-20-pres-districts.png")
    fig.show()
    
    
if __name__ == "__main__":
    main()

The code does work, but it has two problems: 1) The background is not transparent, 2) The size of the map is kind of small compared to what I expected. Map of Texas

How can I make the map larger and ensure that a transparent background is used? I'm using Orca to output the images.


Solution

  • I am not sure, but maybe this will help:

    # transparent background
    fig.layout.paper_bgcolor = "rgba(0,0,0,0)"
    fig.layout.plot_bgcolor = "rgba(0,0,0,0)"
    
    # set margins
    fig.update_layout(
        margin_t=0, margin_b=0,
        margin_l=0, margin_r=0
    )
    

    Does it work? Leave a comment, please.