-
Notifications
You must be signed in to change notification settings - Fork 1
Figure 6: GeoPandas / spatial data - choropleth map - area with rivers and cities of the states of the USA #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Found 1 changed notebook. Review the changes at https://app.gitnotebooks.com/GenericMappingTools/pygmt-paper-figures/pull/6 |
|
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. |
|
This example highlights GeoPandas integration in PyGMT. A The script below plots three different datasets (available from https://www.naturalearthdata.com/) with different geometrie.
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()
|
|
Your example looks quite promising, but I get the following error when running the code:
Will look it in detail tomorrow or within the next days. |
|
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 |
Co-authored-by: Michael Grund <23025878+michaelgrund@users.noreply.github.com>
Co-authored-by: Michael Grund <23025878+michaelgrund@users.noreply.github.com>
Co-authored-by: Dongdong Tian <seisman.info@gmail.com>
Thanks! Also like this map. But Natural Earth does not provide such detailed data of Chicago which can be used for the choropleth part. If we want to have the same datasource for all datasets, we probably will go with the USA example showing the area of the different states with rivers and cities. Now need to think about Alaska. It looks a bit strange when just plotting it together with the rest of the USA. Sometimes Alaska is placed seperatly as an inset; maybe we can do this? Edit: See review by Dongdong #6 (comment) . |
Co-authored-by: Dongdong Tian <seisman.info@gmail.com>
| # Add Alaska and Hawaii separately in the lower left corner | ||
| for xshift, region in zip(["0.9c", "2.3c"], [[172, 230, 51, 72], [-168, -154, 18, 29]]): | ||
| with fig.shift_origin(xshift=xshift): | ||
| fig.plot( | ||
| data=states, | ||
| region=region, | ||
| projection="M2.5c", | ||
| cmap=True, | ||
| pen="0.2p,gray50", | ||
| fill="+z", | ||
| aspatial="Z=area_sqkm" | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depending on how we describe this figure in the manuscript, maybe it makes sense to move the code for insets up to the code part for plotting the polygons of the main map (currently line 18).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would change the region and projection settings and we have to set region and projection again when plotting rivers and cities.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's true. We do not use Figure.inset here.
| fig = pygmt.Figure() | ||
| fig.basemap(projection="L-96/35/33/41/12c", region=[-126, -66, 25, 49], frame="+n") | ||
|
|
||
| pygmt.makecpt(cmap="bilbao", series=[0, states["area_sqkm"].max()]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe use a different CPT or a different range, to avoid polygons that are too light or too dark?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe "hawaii" is better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, from the CPTs I tested I think "hawaii" is the best (even I am not really a fan of the colors in this colormap itself).
Co-authored-by: Dongdong Tian <seisman.info@gmail.com>
| clearance="0.05c+tO", | ||
| ) | ||
|
|
||
| # Add Alaska and Hawaii separately in the lower left corner |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, we set the region for Alaska and Hawaii manually. Ideally, we should be able to get the region from the data directly. The tricky thing is that Hawaii has many small islands, and the region is [-178., -154., 18., 29.]. The code below removes small islands with area < 1.0e8 m^2, and then the region becomes [-161., -154., 18., 23.]. I'm wondering if the code below is better, although we need to explain more details in the main text.
# Add Alaska and Hawaii separately in the lower left corner
for name, xshift in zip(["Alaska", "Hawaii"], ["0.9c", "2.5c"]):
substates = states[(states["name"] == name)]
substates = substates.explode()
substates = substates[substates.to_crs(epsg=6933).area > 1.0e8].dissolve()
region = pygmt.info(substates, spacing=1)
with fig.shift_origin(xshift=xshift):
fig.plot(
data=substates,
region=region,
projection="M2c",
cmap=True,
pen="0.2p,gray50",
fill="+z",
aspatial="Z=area_sqkm",
)| rivers = rivers[rivers.intersects(states.union_all())] | ||
| cities = cities[cities["adm0name"] == "United States of America"] | ||
|
|
||
| states["area_sqkm"] = states.to_crs(epsg=6933).area / 10 ** 9 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original dataset has the area_sqkm column with zero values. That's why we compute the areas and store them in this column. But, since the area is in units of 1000 km^2, I feel the column name is more confusing. Maybe we just save it to a new column "area" instead?
















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