Skip to content

Conversation

@yvonnefroehlich
Copy link
Member

@yvonnefroehlich yvonnefroehlich commented Dec 24, 2024

This PR adds a JN for GeoPandas - spatial data - GeoDataFrame:

  • line geometry - pen parameter
  • polygon geometry - cmap, aspatial parameters

@gitnotebooks
Copy link

gitnotebooks bot commented Dec 24, 2024

Found 1 changed notebook. Review the changes at https://app.gitnotebooks.com/GenericMappingTools/pygmt-paper-figures/pull/6

@seisman seisman changed the title Figure XY: GeoPandas Figure 6: GeoPandas Oct 17, 2025
@seisman seisman changed the title Figure 6: GeoPandas Figure 6: GeoPandas7 Oct 17, 2025
@seisman seisman changed the title Figure 6: GeoPandas7 Figure 7: GeoPandas Oct 17, 2025
@seisman seisman mentioned this pull request Nov 7, 2025
3 tasks
@seisman
Copy link
Member

seisman commented Nov 7, 2025

I'm unsure if we need this example. As I understand it, PyGMT can plot GeoPandas objects, but its functionality for processing them is limited since the aspatial metadata will be lost during processing.

@yvonnefroehlich
Copy link
Member Author

I'm unsure if we need this example. As I understand it, PyGMT can plot GeoPandas objects, but its functionality for processing them is limited since the aspatial metadata will be lost during processing.

I think the idea of having a choropleth map is, to show that there is functionality extending the feature available in GMT.

@seisman
Copy link
Member

seisman commented Nov 19, 2025

This example highlights GeoPandas integration in PyGMT. A geopandas.GeoDataFrame may contain any of the standard geometry types: Point, LineString, MultiLineString, Polygon, and MultiPolygon.

The script below plots three different datasets (available from https://www.naturalearthdata.com/) with different geometrie.

  • world — country boundaries represented by Polygon and MultiPolygon geometries
  • rivers — major rivers represented by LineString geometries
  • cities — populated places represented by Point geometries

So, only MultiLineString is not covered.

import pygmt
import geopandas as gpd

world = gpd.read_file("https://naciscdn.org/naturalearth/50m/cultural/ne_50m_admin_0_countries.zip")
rivers = gpd.read_file("https://naciscdn.org/naturalearth/110m/physical/ne_110m_rivers_lake_centerlines.zip")  
cities = gpd.read_file("https://naciscdn.org/naturalearth/110m/cultural/ne_110m_populated_places_simple.zip")

world["POP_EST"] *= 1.0e-5

fig = pygmt.Figure()
fig.basemap(region="=SA", projection="M15c", frame=True)
fig.plot(data=world, pen="0.5p,black", fill="lightgreen")
pygmt.makecpt(cmap="turbo", series=(0, 3000, 100))
fig.plot(
    data=world,
    pen="0.2p,gray10",
    fill="+z",
    cmap=True,
    aspatial="Z=POP_EST",
)
fig.colorbar(frame=True)
fig.plot(data=rivers, pen="1p,blue")
fig.plot(data=cities, style="c0.1c", fill="red", pen="black")
fig.text(x=cities.geometry.x, y=cities.geometry.y, text=cities["name"], font="10p,Helvetica-Bold,black", offset="0.2c/0.2c")
fig.show()
map

@yvonnefroehlich
Copy link
Member Author

yvonnefroehlich commented Nov 19, 2025

Your example looks quite promising, but I get the following error when running the code:

UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-7: character maps to
encoding with 'cp1252' codec failed

Will look it in detail tomorrow or within the next days.

@seisman seisman changed the title Figure 7: GeoPandas Figure 6: GeoPandas Nov 20, 2025
@seisman
Copy link
Member

seisman commented Nov 20, 2025

It's likely because the city names contain non-ASCII characters, which doesn't work well in your console.

This is a likely solution for you:

cities["name"] = cities["name"].apply(lambda x: x.encode("utf-8", errors="ignore").decode("utf-8"))

@yvonnefroehlich
Copy link
Member Author

It's likely because the city names contain non-ASCII characters, which doesn't work well in your console.

This is a likely solution for you:

cities["name"] = cities["name"].apply(lambda x: x.encode("utf-8", errors="ignore").decode("utf-8"))

Oh, thanks! I already tried something similar, but it did solve the problem yet. For now, I focus on the geometry column of the dataframe, then the codes work.

@yvonnefroehlich
Copy link
Member Author

Using region="=SA" shows that country codes are supported. But the overlapping labels for the cities between 5°-25° North do not look nice.

region="SA" region=[-89, -33, -56.5, 9.7]
Fig7_PyGMT_geopandas_completregion Fig7_PyGMT_geopandas_smallerregion

rivers = gpd.read_file("https://naciscdn.org/naturalearth/110m/physical/ne_110m_rivers_lake_centerlines.zip")
cities = gpd.read_file("https://naciscdn.org/naturalearth/110m/cultural/ne_110m_populated_places_simple.zip")

world["POP_EST"] *= 1.0e-5
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Express the population in millions.

Suggested change
world["POP_EST"] *= 1.0e-5
world["POP_EST"] *= 1.0e-6


fig = pygmt.Figure()
fig.basemap(region=region, projection="M15c", frame=True)
pygmt.makecpt(cmap="batlow", series=(0, 2700, 100)) # 30000
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pygmt.makecpt(cmap="batlow", series=(0, 2700, 100)) # 30000
pygmt.makecpt(cmap="batlow", series=(0, 270, 10)) # 30000

cmap=True,
aspatial="Z=POP_EST",
)
fig.colorbar(frame=["x+lPopulation", "y+l*10e-5"])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fig.colorbar(frame=["x+lPopulation", "y+l*10e-5"])
fig.colorbar(frame=["x+lPopulation (millions)"])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants