Search code examples
pythonmatplotlibgeopandas

Why are line plots in geopandas ignoring plot order when it comes to display layering


I have been experimenting with geopandas and some data exported from openstreetmaps as part of a community project I am working on. To trial the data visualisation side I have taken an export of a section of town and plotted it using geopandas. This worked except that regardless of the order I plot the layers the road layers will appear on top of everything else.

I have tried googling a solution and everythign indicates that the order you perform the plots should dictate the layering, with the last thing to be plotted appearing on top of everything else. Applying this logic the road lines should be underneath the buidings and the spoofed gps location points? can someone please advise how I fix this such that I can control which layer is on top?

enter image description here

import matplotlib.pyplot as plt
import geopandas as gpd
import numpy as np

# import and clean up map data
derby_roads = gpd.read_file('map/roads.geojson')
derby_roads_clean = derby_roads[derby_roads.highway.str.contains('motorway|trunk|primary|secondary|tertiary|residential')]
derby_buildings = gpd.read_file('map/buildings.geojson')
#print(derby_roads_clean)
#print(derby_buildings.head())

# generate random gps data
# min x -1.4879, max x -1.4407
# min y 52.8801, max y 52.8962
points_x = np.random.uniform(-1.4879, -1.4407, size = (50,))
points_y = np.random.uniform(52.8801, 52.8962, size = (50,))
points_z = np.random.uniform(0, 100, size = (50,))
gdf = gpd.GeoDataFrame(points_z, geometry=gpd.points_from_xy(points_x,points_y))
print(gdf.head())

# Create Matplotlib figure
fig, ax = plt.subplots()## configure axis
ax.set_aspect('equal')
ax.set_frame_on(False)
ax.get_xaxis().set_ticks([])
ax.get_xaxis().set_ticklabels([])
ax.get_yaxis().set_ticks([])
ax.get_yaxis().set_ticklabels([])

# plot map data
derby_roads.plot(ax=ax, color='#e6e6e6')
derby_roads_clean.plot(ax=ax, color='grey')
derby_buildings.plot(ax=ax, color='#000000')
gdf.plot(ax=ax, color='red')




#mng = plt.get_current_fig_manager()
#mng.full_screen_toggle()


plt.tight_layout()
plt.show()

Solution

  • You have specify zorder. (https://matplotlib.org/3.1.1/gallery/misc/zorder_demo.html)

    In your case it should be like this

    derby_roads.plot(ax=ax, color='#e6e6e6', zorder=1)
    derby_roads_clean.plot(ax=ax, color='grey', zorder=2)
    derby_buildings.plot(ax=ax, color='#000000', zorder=3)
    gdf.plot(ax=ax, color='red', zorder=4)