【问题标题】:Difficulty combining geom_path and geom_text on ggplot map在 ggplot 地图上难以结合 geom_path 和 geom_text
【发布时间】:2021-07-20 14:59:06
【问题描述】:

我正在尝试使用 geom_path 和 geom_text 创建带标签的地图,但进展不顺利。我可以分别使用每个 geom_path 和 geom_text,但我似乎无法让它们一起工作。我认为它与 geom_polygon 有关,但我不确定是什么。

这是我为映射准备 shapefile 的方式:

meck.hiv <- as(meck.hiv, "Spatial")
meck.hiv@data$seq_id <- seq(1:nrow(meck.hiv@data)) #create unique id for each polygon
meck.hiv@data$id <- rownames(meck.hiv@data)
meck.hivdf <- fortify(meck.hiv) #fortify the data
zipcodedf <- merge(meck.hivdf, meck.hiv@data,
               by = "id")# merge the "fortified" data with the data from our spatial object
cnames <- aggregate(cbind(long, lat) ~ zip, data=zipcodedf, FUN=function(x)mean(range(x))) #get the names of our zipcode (and center the coordinates for labels)

有了这个,我可以得到以下地图:

有标签,没有路径:

p2 <- ggplot(data = zipcodedf, aes(x = long, y = lat)) +
  geom_polygon(aes(group=group, fill=hispanic.dis)) +
  geom_text(data=cnames, aes(long, lat, label = zip), size=3, fontface='bold', color="black")+ #This put in zip code names
  scale_fill_brewer(breaks=c(1, 2, 3, 4, 5, 6, 7), labels=c("<5", "5-10", "11-15", "16-20", "21-25", "26-30", "31+"), palette="Reds",
                    na.value="darkgrey") +  
  coord_equal() +
  theme(panel.background= element_rect(color="black")) +
  theme(axis.title = element_blank(), axis.text = element_blank()) +
  labs(title = "Hispanic Population by Zip Code", fill="Hispanic Population (% of Total)")

Resulting map with labels but no path

路径,但没有标签:

p3 <- ggplot(data = zipcodedf, aes(x = long, y = lat, group = group, fill = hispanic.dis)) +
  geom_polygon() +
  geom_path(color = "black", size = 0.2)+ #Oddly, use of geom_path with the above leads to weird stuff, but we can customize map lines without labels here
  scale_fill_brewer(breaks=c(1, 2, 3, 4, 5, 6, 7), labels=c("<5", "5-10", "11-15", "16-20", "21-25", "26-30", "31+"), palette="Reds",
                    na.value="darkgrey") + 
  coord_equal() +
  theme(panel.background=element_blank())+
  theme(panel.background= element_rect(color="black")) +
  theme(axis.title = element_blank(), axis.text = element_blank()) +
  labs(title = "Hispanic Population by Zip Code", fill="Hispanic Population(% of Total)")

Resulting path with paths but no labels

尝试合并

p4 <- ggplot(data = zipcodedf, aes(x = long, y = lat)) +
  geom_polygon(aes(group=group, fill=hispanic.dis)) +
  geom_text(data=cnames, aes(long, lat, label = zip), size=3, fontface='bold', color="black")+
  geom_path(color = "black", size = 0.2)+ #Oddly, use of geom_path with the above leads to weird stuff, but we can customize map lines without labels here
  scale_fill_brewer(breaks=c(1, 2, 3, 4, 5, 6, 7), labels=c("<5", "5-10", "11-15", "16-20", "21-25", "26-30", "31+"), palette="Reds",
                    na.value="darkgrey") + 
  coord_equal() +
  theme(panel.background=element_blank())+
  theme(panel.background= element_rect(color="black")) +
  theme(axis.title = element_blank(), axis.text = element_blank()) +
  labs(title = "Hispanic Population by Zip Code", fill="Hispanic Population(% of Total)")

Resulting screwed up plot with paths and labels

我的故障排除表明 geom_path 如何与 geom_polygon 和 ggplot() 进行交互,但是如果我将所有指令移到 geom_polygon 中,路径根本不会显示(尽管会生成一个图),如果我将所有指令移到 ggplot() 中,我会收到一个错误:“FUN 中的错误(X[[i]],...):找不到对象 'group'”(如下)。

p5 <- ggplot(data = zipcodedf, aes(x = long, y = lat, group = group, fill = hispanic.dis)) +
  geom_polygon() +
  geom_path(color = "black", size = 0.2)+ 
  geom_text(data=cnames, mapping=aes(x=long, y=lat))+#Oddly, use of geom_path with the above leads to weird stuff, but we can customize map lines without labels here
  scale_fill_brewer(breaks=c(1, 2, 3, 4, 5, 6, 7), labels=c("<5", "5-10", "11-15", "16-20", "21-25", "26-30", "31+"), palette="Reds",
                    na.value="darkgrey") + 
  coord_equal() +
  theme(panel.background=element_blank())+
  theme(panel.background= element_rect(color="black")) +
  theme(axis.title = element_blank(), axis.text = element_blank()) +
  labs(title = "Hispanic Population by Zip Code", fill="Hispanic Population(% of Total)")

感谢任何帮助。如果我需要提供更多信息,请告诉我。

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    {ggplot2} 的分层和继承有时会令人困惑。我希望以下内容有所帮助。还要检查你是否真的想要一个“额外的”geom_path() 层。感觉就像你想描绘/突出县界。另请注意,示例中使用color 为图层设置boundary(line) 颜色。

    我必须模仿您的问题,因为您没有提供可重现的示例。初始代码是为我获取北卡罗来纳州的地图数据。我为县名构建了一个 cnames 数据框。您应该能够将此应用于县级的邮政编码问题... :)

    library(dplyr)
    library(ggplot)
    library(maps)    # helper package to get some map data
    library(mapdata) # helper for some map data
    
    counties <- map_data("county") %>% filter(region == "north carolina")
    head(counties)
    

    产生一个数据框

           long      lat group order         region subregion
    1 -79.53800 35.84424  1857 54915 north carolina  alamance
    2 -79.54372 35.89008  1857 54916 north carolina  alamance
    3 -79.53800 35.98175  1857 54917 north carolina  alamance
    4 -79.52081 36.23385  1857 54918 north carolina  alamance
    5 -79.26298 36.23385  1857 54919 north carolina  alamance
    6 -79.27444 35.90726  1857 54920 north carolina  alamance
    

    仅绘制县(注意:这将是您的邮政编码级别)。 为了解释层继承的原理,我在层调用中“设置”了所有参数(即geom_polygon()):

    ggplot() + 
      geom_polygon(data = counties
                  , aes(x = long, y = lat, group = group)  # aesthetic mapping
                  , color = "white"                        # fixed value for "line"
                  , fill = "lightblue")                    # fixed value for "fill"
    

    如果您现在添加geom_path() 图层而不赋予其美感,则情节不会改变。检查我是否将颜色设置为蓝色,将线条大小设置为 2 以用于演示目的。

    ggplot() + 
      geom_polygon(data = counties, aes(x = long, y = lat, group = group), colour = "white", fill = "lightblue") + 
    # ---------------- adding a layer with no aesthetics -----------
      geom_path(color = "blue", size = 2)  # ... no joy!
    

    如果您现在将数据和美学移动到ggplot()“base”-layer,路径也将继承美学。在这种情况下,路径将绘制分组纬度/经度位置的“轮廓”。 geom_path() 的层顺序和颜色/大小将“覆盖”白色多边形线。

    ggplot(data = counties, aes(x = long, y = lat, group = group)) + 
      geom_polygon( colour = "white", fill = "lightblue") + 
    #------------ path layer with inherited "polygon" grouping
      geom_path(color = "blue", size = 2) 
    

    接下来让我们通过平均不同多边形段点的纬度/经度值来创建(邮政编码:))又名文本标签。

    cnames <- counties %>% 
       group_by(subregion) %>% 
       summarise(long = mean(long), lat = mean(lat) # averaging for "mid"-point
    )
    > cnames
    # A tibble: 100 x 3
       subregion  long   lat
       <chr>     <dbl> <dbl>
     1 alamance  -79.4  36.0
     2 alexander -81.2  35.9
     3 alleghany -81.1  36.5
    

    现在添加一个geom_text() 层以显示(邮政编码)又名子区域名称。

    ggplot(data = counties, aes(x = long, y = lat, group = group)) + 
       geom_polygon( colour = "white", fill = "lightblue") + 
       geom_path(color = "blue", size = 2) +
    # --------------- adding a geom_text() layer 
       geom_text(data = cnames, aes(x = long, y = lat), color = "green")
    ## ------- uuummmppfff throws an error
    Error in FUN(X[[i]], ...) : object 'group' not found
    

    这会引发错误。那为什么呢? ggplot() 调用中的群体美学隐含地被 geom_polygon()geom_path() 理解......但是 geom_text() 存在问题。

    将组美学移动到多边形层...

    ggplot(data = counties, aes(x = long, y = lat)) + 
        geom_polygon( aes(group=group), colour = "white", fill = "lightblue") + 
        geom_path(color = "blue", size = 2) + 
        geom_text(data = cnames, aes(x = long, y = lat, label = "subregion"), color = "green")
    

    成功了,但破坏了 geom_path() 层。
    这里发生的情况是数据点(即纬度/经度)不再分组,并且 ggplot 按照它们在县数据框中出现的顺序连接端点。这些是您在整个情节中看到的曲线。

    因此,您需要为 geom_path 层添加另一个 aes(group=group)! ...假设您真的想要轮廓的路径。

    ggplot(data = counties, aes(x = long, y = lat)) + 
        geom_polygon( aes(group=group), colour = "white", fill = "lightblue") + 
        geom_path(aes(group=group), color = "blue", size = 2) + 
        geom_text(data = cnames, aes(x = long, y = lat, label = "subregion"), color = "green")
    

    显然color = "white"geom_path() 调用覆盖。您可以跳过其中一个。

    根据经验,ggplot 适用于“长”数据表。添加第二个(或更多其他数据对象)的那一刻,请确保跟踪需要和/或从一层继承到另一层的美学。在您的原始示例中,您可以将 geom_path() 向上移动以从 geom_polygon() 调用中获得 group = group 美学。
    如有疑问,请始终在跨层组合(和继承)参数之前为每一层填充 data = ... 和 aes()。

    祝你好运!

    【讨论】:

    • 这太好了,谢谢!事实证明我根本不需要路径。 :) 感谢您的深入解释!
    • 没有问题@Kiran。如果有帮助,我很高兴。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 2021-06-19
    相关资源
    最近更新 更多