19

I have a geopandas dataframe, which consists of the region name(District), the geometry column, and the amount column. My goal is to plot a choropleth map using the method mentioned below https://plotly.com/python/choropleth-maps/#using-geopandas-data-frames

Here’s a snippet of my dataframe

I also checked that my columns were in the right format/type.

enter image description here

And here's the code I used to plot the map

fig = px.choropleth(merged,

                   geojson=merged.geometry,

                   locations=merged.index,

                   color="Amount")

fig.update_geos(fitbounds="locations", visible=False)

fig.show()

It produced the below figure

enter image description here

which is obviously not the right figure. For some reasons, it doesn't show the map, instead it shows a line and when I zoom in, I am able to see the map but it has lines running through it. Like this

enter image description here

Has anyone ran into a similar problem? If so how were you able to resolve it?

The Plotly version I am using is 4.7.0. I have tried upgrading to a most recent version but it still didn’t work.

Any help is greatly appreciated. Please find my code and the data on my github.

jb12n
  • 463
  • 1
  • 4
  • 18
  • 1
    I checked the same result with `px.choropleth_mapbox()`. The map was displayed, but it was not filled by region. I have checked the geometry data, is it in latitude and longitude values? I checked the data from the official [reference page](https://plotly.com/python/mapbox-county-choropleth/). – r-beginners Dec 30 '20 at 15:15
  • @r-beginners The data has a geometry column which holds the polygons/shape for each region. I have updated my question to show the Dtype for each column. – jb12n Dec 30 '20 at 15:45
  • Doesn't the actual data represent latitude and longitude, not the data type? – r-beginners Dec 31 '20 at 00:49
  • Sorry, I am not sure I get your question. – jb12n Dec 31 '20 at 13:06
  • What I wanted to make sure is that this data is correct? `POLYGON ((498847.140 4793516.119, 498839.366 4...` My understanding is that I need the latitude and longitude information. – r-beginners Dec 31 '20 at 13:12
  • Yes, the data is correct because I am able to produce a choropleth map using matplotlib but not with plotly. – jb12n Dec 31 '20 at 16:14
  • 3
    What @r-beginners is saying, is you should try to reproject your GeoDataFrame into WGS84 first. For instance, gdf.to_crs(pyproj.CRS.from_epsg(4326), inplace=True). All examples on the web seems to use geodataframes in this projection which isn't unexpected... Note that matplotlib is only a canvas, so you won't have any trouble plotting your dataframe whatever your projection is. – tgrandje Jan 05 '21 at 12:06
  • @tgrandje, after projecting the geodataframe into the WGS84, I am now able to render the map. Do you want to post the answer and then I will mark it as the correct answer? – jb12n Jan 05 '21 at 13:07
  • 2
    I'll leave it to @r-beginners who deserves it ! – tgrandje Jan 05 '21 at 13:14
  • Great, @r-beginners, please go ahead and post the answer. – jb12n Jan 05 '21 at 13:23
  • 2
    @Poopah, you can post your own answer. That's the best way to go. – r-beginners Jan 05 '21 at 13:48

2 Answers2

32

I'll give you the answer to @tgrandje's comment that solved the problem. Thanks to @Poopah and @tgrandje for the opportunity to raise the answer.

import pandas as pd
import plotly.express as px
import geopandas as gpd
import pyproj

# reading in the shapefile
fp = "./data/"
map_df = gpd.read_file(fp)
map_df.to_crs(pyproj.CRS.from_epsg(4326), inplace=True)

df = pd.read_csv("./data/loans_amount.csv")
# join the geodataframe with the cleaned up csv dataframe
merged = map_df.set_index('District').join(df.set_index('District'))
#merged = merged.reset_index()
merged.head()

fig = px.choropleth(merged, geojson=merged.geometry, locations=merged.index, color="Amount")
fig.update_geos(fitbounds="locations", visible=False)

fig.show()

enter image description here

r-beginners
  • 31,170
  • 3
  • 14
  • 32
0

Another possible source of the problem (when using Plotly graph_objects) is mentioned in this answer over at gis.stackexchange.com:

  1. The locations argument has to point to a column that matches GeoJSON's 'id's.
  2. The geojson argument expects a dictionary.

To solve your problem, you should: (i) point locations to the dataframe's index, and (ii) turn your GeoJSON string to a dictionary.

It's not exactly the answer to your question, but I thought my problem was the same as yours and this helped me. So I am including the answer here.

yotka
  • 1,002
  • 2
  • 11
  • 19