绘制欧洲国家人口Cartogram报错及相关技术咨询
Hi there! Let's work through your cartogram issues step by step—you're so close to getting this right!
1. Fixing the Projection Error
The core problem here is that you were trying to use a geographic coordinate system (WGS84, lon/lat) for the cartogram, but cartogram_cont requires a projected (planar) coordinate system—specifically an equal-area projection, since the algorithm manipulates polygon areas to match your target variable.
Your earlier st_transform call was misconfigured: the coords parameter is only for converting non-spatial data frames to sf objects, but your sf object already had geometry attached. Here's the correct workflow:
- First, convert your filtered sp object to sf format
- Reproject it to an equal-area projection designed for Europe (I recommend EPSG:3035, the European Equal Area projection)
- Then run the cartogram function
Here's the corrected code snippet:
# Convert filtered sp object to sf sf_obj = st_as_sf(mapsimple) # Reproject to European equal-area projection (EPSG:3035) sf_proj = st_transform(sf_obj, crs = 3035) # Now create the cartogram without errors! cartogram = cartogram_cont(sf_proj, "POP2005", itermax = 7) # Plot the result plot(st_geometry(cartogram), main = "European Population Cartogram (2005)")
2. Using Other Variables Instead of POP2005
Switching to a different variable is straightforward—you just need to replace "POP2005" with the name of any positive numeric variable in your sf object (e.g., GDP, population density, total area).
For example, if you wanted to make a cartogram based on 2005 GDP:
# Assuming your sf_proj has a column named "GDP2005" cartogram_gdp = cartogram_cont(sf_proj, "GDP2005", itermax = 7)
Just make sure your variable has no NA values or negative numbers—you can check with summary(sf_proj$your_variable) and filter out bad rows if needed.
3. What Does the itermax Parameter Mean?
The itermax setting controls how many times the cartogram algorithm iterates to adjust polygon areas. Here's a simple breakdown:
- Each iteration tweaks the size of each country's polygon to get closer to matching the proportional size of your target variable (e.g., POP2005)
- A higher
itermax(like your 7) will make the area proportions more accurate, but it also takes longer to compute and can lead to more distorted, less recognizable country shapes - The default value is usually 5, which balances accuracy and readability for most use cases
Full Working Example
Here's a complete, runnable script that ties everything together:
# Load required packages library(maptools) library(cartogram) library(sf) # Define your target European countries countries = c('Austria', 'Belgium', 'Bulgaria', 'Cyprus', 'Czech Republic', 'Denmark', 'Estonia', 'Finland', 'France', 'Germany', 'Greece', 'Hungary', 'Iceland', 'Ireland', 'Italy', 'Latvia', 'Lithuania', 'Luxembourg', 'Malta', 'Netherlands', 'Norway', 'Poland', 'Portugal', 'Slovenia', 'Spain', 'Sweden', 'United Kingdom') # Load and filter the world map data data(wrld_simpl) mapsimple = wrld_simpl[wrld_simpl$NAME %in% countries, ] # Convert to sf and reproject to equal-area projection sf_obj = st_as_sf(mapsimple) sf_proj = st_transform(sf_obj, crs = 3035) # Create population cartogram cart_pop = cartogram_cont(sf_proj, "POP2005", itermax = 7) # Plot with country labels for clarity plot(st_geometry(cart_pop), main = "European Population Cartogram (2005)") text(st_centroid(st_geometry(cart_pop)), labels = cart_pop$NAME, cex = 0.6)
内容的提问来源于stack exchange,提问作者Dan

