Why Is My GeoPandas Plot Blank or Empty? How to Fix It
Problem statement
You call .plot() on a GeoDataFrame and nothing useful appears. The figure opens but the axes are empty, the saved image is white, or in a script no window shows at all.
What users usually mean is one of these symptoms:
- a blank white figure with empty axes and no geometry
- a window that opens and closes immediately in a script
- a saved PNG that is completely white
- axes that render but no shapes are drawn
- a choropleth where every feature is the same flat color
In most cases, the real cause is one of these data or display issues:
- the GeoDataFrame is empty or every geometry is null
- the figure was never displayed because
plt.show()is missing - a filter removed every feature before plotting
- the column used for coloring is all
NaN - you plotted before actually reading the data
- the extent is zero-area, so everything draws on a single point
- an existing
axwas reused and the data went to a different axes
The practical fix is to confirm the data has visible geometry, then confirm the figure is actually being shown.
Quick answer
If your GeoPandas plot is blank or empty:
- Print
len(gdf)andgdf.geometry.isna().sum()to confirm there is geometry to draw. - Check
gdf.geometry.is_empty.sum()for empty geometries. - Make sure you call
plt.show()in a script, or use an inline backend in Jupyter. - If coloring by a column, check that column for
NaNwithgdf["value"].isna().sum(). - Print
gdf.total_boundsto confirm the extent is not zero-area. - Plot onto an explicit
axfromplt.subplots()so the data lands where you expect.
import geopandas as gpd
import matplotlib.pyplot as plt
gdf = gpd.read_file("data/regions.gpkg")
print("Rows:", len(gdf))
print("Null geometries:", gdf.geometry.isna().sum())
print("Empty geometries:", gdf.geometry.is_empty.sum())
print("Bounds:", gdf.total_bounds)
fig, ax = plt.subplots(figsize=(8, 6))
gdf.plot(ax=ax, edgecolor="black")
plt.show()
Data or display?
Step-by-step solution
Step 1: Check that the GeoDataFrame is not empty
A blank plot is often a blank dataset. If the read or a filter returned nothing, there is nothing to draw.
import geopandas as gpd
gdf = gpd.read_file("data/regions.gpkg")
print("Rows:", len(gdf))
print(gdf.head())
If len(gdf) is 0, the problem is upstream of plotting. Check the file path, the layer name, and any filter you applied before .plot().
Step 2: Check for null and empty geometries
A GeoDataFrame can have rows but still draw nothing if the geometry column is all null or all empty.
import geopandas as gpd
gdf = gpd.read_file("data/regions.gpkg")
print("Null geometries:", gdf.geometry.isna().sum())
print("Empty geometries:", gdf.geometry.is_empty.sum())
Keep only rows that have real geometry before plotting:
gdf = gdf[gdf.geometry.notna() & ~gdf.geometry.is_empty]
print("Drawable rows:", len(gdf))
If nothing remains after this filter, the source data has no usable geometry.
Step 3: Make sure the figure is actually displayed
In a plain Python script, building a plot does not show it. Without plt.show(), the script can finish and the window never appears.
import geopandas as gpd
import matplotlib.pyplot as plt
gdf = gpd.read_file("data/regions.gpkg")
gdf.plot(edgecolor="black")
plt.show()
In Jupyter, the figure usually renders automatically with the inline backend. If it does not, run %matplotlib inline once in a cell. If you are saving instead of showing, use plt.savefig("map.png") and open the file.
Step 4: Check the column used for coloring for NaN
When you plot a choropleth with column=, rows where that column is NaN are not colored. If every value is NaN, the map looks blank or flat.
import geopandas as gpd
gdf = gpd.read_file("data/regions.gpkg")
print("NaN values in column:", gdf["population"].isna().sum())
print(gdf["population"].describe())
If the column is all NaN, fix the data or choose a column that has values. You can also make missing values visible:
import matplotlib.pyplot as plt
ax = gdf.plot(
column="population",
legend=True,
missing_kwds={"color": "lightgray", "label": "No data"},
)
plt.show()
Step 5: Check the CRS and extent
A zero-area or degenerate extent can make every feature collapse onto a single point, which looks like an empty map.
import geopandas as gpd
gdf = gpd.read_file("data/regions.gpkg")
print("CRS:", gdf.crs)
print("Bounds:", gdf.total_bounds)
gdf.total_bounds returns:
[minx, miny, maxx, maxy]
If minx == maxx and miny == maxy, the data covers no area, so it draws as a dot. That usually means only one identical point remains, or the geometry is degenerate. A missing CRS does not by itself blank the plot, but it is worth confirming while you inspect the data.
Step 6: Plot onto an explicit axes
If you reuse an ax from an earlier figure, your data can be drawn onto axes you are not looking at. Create a fresh figure and axes for each plot.
import geopandas as gpd
import matplotlib.pyplot as plt
gdf = gpd.read_file("data/regions.gpkg")
fig, ax = plt.subplots(figsize=(8, 6))
gdf.plot(ax=ax, edgecolor="black")
plt.show()
This makes it explicit which axes the geometry goes to, which removes a common source of "nothing shows up" confusion.
Code examples
Example 1: Full diagnostic before plotting
import geopandas as gpd
import matplotlib.pyplot as plt
gdf = gpd.read_file("data/regions.gpkg")
print("Rows:", len(gdf))
print("Null geometries:", gdf.geometry.isna().sum())
print("Empty geometries:", gdf.geometry.is_empty.sum())
print("CRS:", gdf.crs)
print("Bounds:", gdf.total_bounds)
fig, ax = plt.subplots(figsize=(8, 6))
gdf.plot(ax=ax, edgecolor="black")
plt.show()
This sequence usually tells you immediately whether the problem is the data or the display.
Example 2: Drop null and empty geometries, then plot
import geopandas as gpd
import matplotlib.pyplot as plt
gdf = gpd.read_file("data/regions.gpkg")
clean = gdf[gdf.geometry.notna() & ~gdf.geometry.is_empty]
print("Original rows:", len(gdf))
print("Drawable rows:", len(clean))
clean.plot(edgecolor="black", figsize=(8, 6))
plt.show()
If clean is empty, the source file has no usable geometry and plotting cannot help.
Example 3: Color by a column safely
import geopandas as gpd
import matplotlib.pyplot as plt
gdf = gpd.read_file("data/regions.gpkg")
print("NaN in column:", gdf["population"].isna().sum())
fig, ax = plt.subplots(figsize=(8, 6))
gdf.plot(
column="population",
legend=True,
missing_kwds={"color": "lightgray", "label": "No data"},
ax=ax,
)
plt.show()
Rows with NaN now draw in gray instead of disappearing, so the map is no longer blank.
Example 4: Save the figure instead of showing it
import geopandas as gpd
import matplotlib.pyplot as plt
gdf = gpd.read_file("data/regions.gpkg")
fig, ax = plt.subplots(figsize=(8, 6))
gdf.plot(ax=ax, edgecolor="black")
fig.savefig("output/map.png", dpi=150, bbox_inches="tight")
plt.close(fig)
Use this in headless scripts where no display is available. If the saved PNG is still white, the data was empty, not the display.
Explanation
A GeoPandas plot has two separate parts: the Matplotlib axes and the geometry drawn onto them. A blank figure means the axes were created but no geometry reached them, or the figure was never shown.
The most common causes are:
-
no drawable geometry
An empty GeoDataFrame, all-null geometry, or all-empty geometry leaves the axes with nothing to draw. -
the figure was never displayed
In a script,.plot()builds the figure butplt.show()is what renders it. Without it, the work is silently discarded. -
all values are NaN in the color column
Withcolumn=, features that areNaNare not assigned a color, so a fullyNaNcolumn produces a blank or flat map. -
degenerate extent
If every coordinate is identical, the data has zero area and collapses to a single point. -
wrong axes
Passing a reusedaxsends the geometry to a figure you are not viewing.
The key distinction is between an empty axes and empty data. An empty axes with valid data points to a display problem such as a missing plt.show() or the wrong backend. An empty axes with no valid geometry points to a data problem you must fix before plotting.
Edge cases or notes
Jupyter versus a script
In Jupyter, the inline backend renders the last expression of a cell automatically, so a missing plt.show() is rarely the issue. In a plain script you almost always need plt.show() to see a window.
Interactive backends
If plt.show() opens a window that closes instantly, you may have a non-interactive backend. Check it with matplotlib.get_backend(). On a headless server there is no display, so save the figure with savefig() instead of showing it.
Saving versus showing
plt.show() renders to a window and savefig() writes to a file. Calling plt.show() before savefig() can leave you with a blank file on some backends, because the figure may be cleared after display. Save first, then show, or use separate figures.
Plotting before reading the data
If you build the figure before the read completes or before assigning the result, you can plot an empty or stale object. Confirm gdf is populated immediately before .plot().
All geometries filtered out
A chained filter such as gdf[gdf["area"] > 1000] can quietly return zero rows. Print len() after each filter so you know when the data became empty.
A single point looks like nothing
One point on default axes can be invisible at the chosen scale. Increase markersize or set explicit axis limits so the feature is easy to see.
Internal links
- How to Plot Maps in Python with GeoPandas and Matplotlib
- How to Save a Map as an Image in Python with Matplotlib
- Why Does My GeoPandas Map Look Upside Down?
- How to Remove Null and Empty Geometries in GeoPandas
- CRS Not Found Error in GeoPandas: Causes and Fixes
- How to Create a Choropleth Map in Python with GeoPandas
FAQ
Why is my GeoPandas plot blank?
Usually because there is no drawable geometry or the figure was never shown. Check len(gdf), gdf.geometry.isna().sum(), and gdf.geometry.is_empty.sum(), then make sure you call plt.show().
Why does nothing appear when I run .plot() in a script?
Building a plot does not display it. In a script you need plt.show() to open a window, or savefig() to write the figure to a file.
Why is my choropleth map all one color or blank?
The column you passed to column= may be all NaN, so no feature gets a color. Check the column with isna().sum() and use missing_kwds to make missing values visible.
Why is my saved map image completely white?
The figure had no geometry to draw, or it was cleared by plt.show() before savefig(). Confirm the GeoDataFrame is not empty and save the figure before showing it.
Why does my GeoPandas plot show axes with coordinate numbers but no shapes?
The axes rendered, so this is a data problem, not a display one: the geometry is null, empty, or filtered out. Run gdf.geometry.notna().sum() and (~gdf.geometry.is_empty).sum() to confirm there is something drawable before plotting.
Why do two layers plot in different places or one disappears off-screen?
The layers are almost certainly in different CRS, so their coordinate ranges do not overlap and one falls outside the visible extent. Reproject one to match the other with layer2 = layer2.to_crs(layer1.crs) before plotting them on the same ax.
Why is my plot blank only when I save with savefig but fine on screen?
You likely called plt.show() before fig.savefig(); some backends clear the figure after display, leaving a white file. Save first, then show, and pass the explicit figure with fig.savefig("map.png") rather than relying on the current figure.
How do I make a single point or tiny feature visible instead of an empty-looking plot?
A lone point can render too small to see at the default scale. Increase markersize and set explicit limits, for example gdf.plot(markersize=50) followed by ax.set_xlim(...), or buffer the point so it has visible area.