Contextily add_basemap inferred zoom level is not valid and changing zoom parameter doesn't fix issue

3.5k views Asked by At

I want to plot the background map of Melbourne behind the plotted points of property addresses.

I used the following code:

import pandas as pd
import geopandas as gpd
from shapely.geometry import shape
import matplotlib.pyplot as plt
import contextily

MELB_PROPERTY_DATA = "https://data.melbourne.vic.gov.au/resource/imwx-szwr.json"

properties = pd.read_json(MELB_PROPERTY_DATA)
properties['the_geom'] = properties['the_geom'].apply(shape)
properties_geo = gpd.GeoDataFrame(properties).set_geometry('the_geom')

ax = properties_geo.plot(markersize=1)
contextily.add_basemap(ax)
plt.show()

At the contextily.add_basemap(ax) line I get the following UserWarning.

contextily\tile.py:632: UserWarning: The inferred zoom level of 30 is not valid for the current tile provider (valid zooms: 0 - 18).

I read the Contextily docs but they don't fix my problem.

Changing the line to contextily.add_basemap(ax, zoom=5) removes the UserWarning but still no background map appears. Similar questions have been asked on SO, but I can't retrofit them to my problem.

I feel like I'm importing lots of libraries for this simple task as well, so if you have any suggestions to fine-tune it that would also be appreciated.

Output chart showing marks for addresses in Melbourne but with no basemap for context

1

There are 1 answers

0
Ryan Ward On BEST ANSWER

I solved this by realising from swatchai's comment that a Coordinate Reference System (CRS) was never defined.

See below for final code, with erroneous lines commented out to show the difference.

import pandas as pd
import geopandas as gpd
from shapely.geometry import shape
import matplotlib.pyplot as plt
import contextily

MELB_PROPERTY_DATA = "https://data.melbourne.vic.gov.au/resource/imwx-szwr.json"

properties = pd.read_json(MELB_PROPERTY_DATA)
properties['the_geom'] = properties['the_geom'].apply(shape)

# properties_geo = gpd.GeoDataFrame(properties).set_geometry('the_geom')
properties_geo = gpd.GeoDataFrame(properties, geometry='the_geom', crs='EPSG:4326')

ax = properties_geo.plot(markersize=1)

# contextily.add_basemap(ax)
contextily.add_basemap(ax, crs=properties_geo.crs.to_string())

plt.show()