使用ggplot绘制热力地图时限制坐标轴导致geom_polygon连线异常
Hey, I've run into this exact issue before! The weird broken lines in your geom_polygon layer are caused by how xlim() and ylim() work in ggplot—let me break it down and show you easy fixes:
What's Going Wrong?
xlim() and ylim() don't just zoom your plot—they permanently remove any data points that fall outside the range you set. When your map polygon (map.df) has vertices outside your xlim/ylim bounds, those points get deleted. The remaining points are still connected in their original order, which creates those messy, incorrect lines.
Fix 1: Use coord_cartesian() (Simplest Solution)
coord_cartesian() is a "soft zoom" tool—it adjusts what you see in the plot without deleting any data. This keeps your polygon intact while still restricting the view to your desired range.
Here's your modified code:
ggplot(2017.fixes, aes(x=Long, y=Lat)) + stat_density_2d(aes(fill = ..density..), geom = "raster", contour=F) + scale_fill_distiller(palette="PuBu", direction=1) + geom_polygon(data=map.df, aes(x=long, y=lat, group=group), color="grey50", fill="grey", na.rm=T) + coord_cartesian(xlim = c(-156.95, -156.4), ylim = c(20.55, 21.05)) + # Replace xlim/ylim with this coord_fixed()
Fix 2: Crop Your Map Data First (For Permanent Trimming)
If you actually want to remove the parts of the map outside your range (not just hide them), you can pre-crop the map data using spatial tools. The sf package makes this straightforward:
- Convert your map data to a spatial object:
library(sf) # Convert map.df to an sf polygon object map_sf <- st_as_sf(map.df, coords = c("long", "lat"), group_by = group)
- Create a bounding box for your desired range:
# Define your crop area as a spatial polygon crop_bounds <- st_bbox(c(xmin = -156.95, xmax = -156.4, ymin = 20.55, ymax = 21.05)) %>% st_as_sfc()
- Crop the map to this bounds:
# Keep only the parts of the map inside your bounds map_cropped <- st_intersection(map_sf, crop_bounds)
- Plot with the cropped map:
ggplot(2017.fixes, aes(x=Long, y=Lat)) + stat_density_2d(aes(fill = ..density..), geom = "raster", contour=F) + scale_fill_distiller(palette="PuBu", direction=1) + geom_sf(data=map_cropped, color="grey50", fill="grey") + # Use geom_sf for spatial objects coord_sf(xlim = c(-156.95, -156.4), ylim = c(20.55, 21.05)) + coord_fixed()
Either of these methods should fix the broken polygon lines you're seeing!
内容的提问来源于stack exchange,提问作者Anke

