【问题标题】:Mapping different states in R using facet wrap使用 facet wrap 在 R 中映射不同的状态
【发布时间】:2017-12-02 13:02:05
【问题描述】:

我正在尝试使用 ggplot2 中的 facet_wrap 将不同的状态映射到多面图的每个方面。我的代码在此处列出,其中“数据集”是一个数据框,其中包含一个名为“状态”的变量,其中包含我希望通过 facet 映射的不同状态的名称。

library(maps)
library(ggplot2)

states <- c('Oklahoma','Arizona','Washington','North     
Dakota','Michigan','Florida')

map <- ggplot(data=datatest) + geom_polygon(data=map_data
('state',region=datatest$state),aes
(x=long,y=lat,group=group),colour='black',fill='white') + 
facet_wrap(~state,ncol=3)

我无法让每个方面都成为不同状态的地图。相反,每个方面都是整个美国的地图,上面显示了六个列出的州。如果有人知道在每个方面本身都是不同状态的情况下使其工作的方法,我将不胜感激。我很确定这与在对 map_data 的调用中如何定义“区域”有关,但我尝试过的任何方法都不起作用。这可能无法完成,但我想我会看看是否有人有想法。谢谢!

【问题讨论】:

  • 您的代码不可重现,因为缺少datatest。请提供一些测试数据。
  • 检查 datatest$state 是否为因子变量,否则将其类型转换为因子变量并查看是否有效。

标签: r ggplot2 facet facet-wrap


【解决方案1】:

state 列不存在于来自map_data 的返回中。在那里,您要查找的列称为region。此外,至少在您的示例中,没有从 datatest 数据中绘制数据。所以,你可以省略它。

这段代码应该可以工作。请注意,我添加了scales = "free",因为我假设您希望每个状态都填充其对应的方面。

ggplot(map_data('state',region=states)
       , aes(x=long,y=lat,group=group)) +
  geom_polygon(colour='black',fill='white') + 
  facet_wrap(~region
             , scales = "free"
             , ncol=3)

给

请注意,使用facet_wrap 将关闭纵横比,因为构面无法处理coord_map 控件。为了使情节更好,我建议分别制作每个状态图,然后使用cowplot 中的plot_grid 将它们拼接在一起。请注意,cowplot 会加载默认主题,因此您需要重置默认主题(使用 theme_set)或显式设置绘图主题(就像我在这里所做的那样):

sepStates <-
  lapply(states, function(thisState){
    ggplot(map_data('state',region=thisState)
           , aes(x=long,y=lat,group=group)) +
      geom_polygon(colour='black',fill='white') +
      facet_wrap(~region) +
      coord_map() +
      theme_void()
  })


library(cowplot)
plot_grid(plotlist = sepStates)

给

如果您想包含来自其他来源的数据,您需要确保它是兼容的。尤其是,您需要确保要作为分面依据的列在两者中被称为相同的事物。

假设您有以下数据要添加到绘图中:

datatest <-
structure(list(zip = c("85246", "85118", "85340", "34958", "33022", 
"32716", "49815", "48069", "48551", "58076", "58213", "58524", 
"73185", "74073", "73148", "98668", "98271", "98290"), city = c("Chandler", 
"Gold Canyon", "Litchfield Park", "Jensen Beach", "Hollywood", 
"Altamonte Springs", "Channing", "Pleasant Ridge", "Flint", "Wahpeton", 
"Ardoch", "Braddock", "Oklahoma City", "Sperry", "Oklahoma City", 
"Vancouver", "Marysville", "Snohomish"), state = c("AZ", "AZ", 
"AZ", "FL", "FL", "FL", "MI", "MI", "MI", "ND", "ND", "ND", "OK", 
"OK", "OK", "WA", "WA", "WA"), latitude = c(33.276539, 33.34, 
33.50835, 27.242402, 26.013368, 28.744752, 46.186913, 42.472235, 
42.978995, 46.271839, 48.204374, 46.596608, 35.551409, 36.306323, 
35.551409, 45.801586, 48.093129, 47.930902), longitude = c(-112.18717, 
-111.42, -112.40523, -80.224613, -80.144217, -81.22328, -88.04546, 
-83.14051, -83.713124, -96.608142, -97.30774, -100.09497, -97.407537, 
-96.02081, -97.407537, -122.520347, -122.21614, -122.03976)), .Names = c("zip", 
"city", "state", "latitude", "longitude"), row.names = c(NA, 
-18L), class = c("tbl_df", "tbl", "data.frame"))

看起来像这样:

     zip              city state latitude  longitude
   <chr>             <chr> <chr>    <dbl>      <dbl>
 1 85246          Chandler    AZ 33.27654 -112.18717
 2 85118       Gold Canyon    AZ 33.34000 -111.42000
 3 85340   Litchfield Park    AZ 33.50835 -112.40523
 4 34958      Jensen Beach    FL 27.24240  -80.22461
 5 33022         Hollywood    FL 26.01337  -80.14422
 6 32716 Altamonte Springs    FL 28.74475  -81.22328
 7 49815          Channing    MI 46.18691  -88.04546
 8 48069    Pleasant Ridge    MI 42.47223  -83.14051
 9 48551             Flint    MI 42.97899  -83.71312
10 58076          Wahpeton    ND 46.27184  -96.60814
11 58213            Ardoch    ND 48.20437  -97.30774
12 58524          Braddock    ND 46.59661 -100.09497
13 73185     Oklahoma City    OK 35.55141  -97.40754
14 74073            Sperry    OK 36.30632  -96.02081
15 73148     Oklahoma City    OK 35.55141  -97.40754
16 98668         Vancouver    WA 45.80159 -122.52035
17 98271        Marysville    WA 48.09313 -122.21614
18 98290         Snohomish    WA 47.93090 -122.03976

如果您想对状态进行分面,则需要将其转换为与地图数据中相同的格式(即全名和小写)并将列称为相同的东西(region 而不是状态) .此外,如果您使列名也全部相同,则最容易。在这里,我添加列以匹配从 map_data 绘制的三个列,并添加一个允许刻面的 region 列:

stateList <-
  setNames(tolower(state.name), state.abb)

datatest$lat <- datatest$latitude
datatest$long <- datatest$longitude
datatest$group <- NA
datatest$region <- stateList[datatest$state]

现在,您可以在绘图中添加geom_point() 线,它会正确显示:

ggplot(map_data('state',region=states)
       , aes(x=long,y=lat,group=group)) +
  geom_polygon(colour='black',fill='white') +
  geom_point(data = datatest) +
  facet_wrap(~region
             , scales = "free"
             , ncol=3)

给予

或者,您可以将其添加到 cowplot 方法中(请注意,我现在只是标题并跳过了刻面)。

sepStates <-
  lapply(states, function(thisState){
    ggplot(map_data('state',region=thisState)
           , aes(x=long,y=lat,group=group)) +
      geom_polygon(colour='black',fill='white') +
      geom_point(data = datatest[datatest$region == tolower(thisState), ]) +
      ggtitle(thisState) +
      coord_map() +
      theme_void() +
      theme(plot.title = element_text(hjust = 0.5))
  })

plot_grid(plotlist = sepStates)

给予

【讨论】:

  • 谢谢 - 这很好用。我需要将天气数据中的点添加到绘图中,但是当我这样做时,地图会再次恢复为旧方式。如何向这些图添加点,并保持它们的良好刻面格式?
  • 这就是为什么您需要提供可重现的数据以及解决您的问题所需的所有部分。我提取了一些数据(来自zipcode 包)作为示例,并展示了如何修改它来满足您的要求。
  • @user8229029 - 回复您现在删除的评论:stackoverflow.com/help/someone-answers
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-23
  • 2016-07-19
  • 2015-08-24
  • 1970-01-01
  • 1970-01-01
  • 2017-10-09
相关资源
最近更新 更多