【问题标题】:geographical/geospatial map with maps() - R带有 maps() - R 的地理/地理空间地图
【发布时间】:2019-11-15 10:44:29
【问题描述】:

我经历了很多问题和文档,由于您需要付费才能使用ggmaps()(因为谷歌云服务),我开始寻找替代方案。我找到了maps(),我正在尝试适应this 解决方案:

data %>%
    rename(x = longitud, y = latitud) %>%
    ggplot() +
        geom_polygon(aes(x = long, y = lat), data = map_data("world")) +
        geom_point(aes(x = x, y = y))

但是,我遇到了一些问题:

  • 如果您绘制上面的代码,您将得到正确的点(智利),但世界地图打印错误(见上图)。
  • 我不需要灰色或彩色地图。我只需要用一种正常的格式(例如,谷歌地图卫星)绘制智利国家。坐标是湖泊/山脉的流动,我想看看我是否可以通过一些视觉扇区来聚集它们。
  • 我只需要一张来自智利的地图,但由于我没有找到,所以我正在使用这张世界地图。有没有办法在不丢失与地图坐标的联系的情况下切割它?

这是数据:

data <- structure(list(latitud = c(-30.6833000183105, -41.4000015258789, 
-43.8189010620117, -34.2731018066406, -47.0666999816895, -40.3166999816895, 
-43.4491996765137, -35.7543983459473, -47.1413993835449, -36.6260986328125, 
-54.0410995483398, -37.2118988037109, -33.3086013793945, -37.2792015075684, 
-35.4524993896484, -36.5856018066406, -18.5832996368408, -18.2325000762939, 
-36.4668998718262, -44.75, -44.6591987609863, -44.5936012268066, 
-28.4647006988525, -28.6996994018555, -28.5118999481201, -28.6718997955322, 
-28.7306003570557, -30.5902996063232, -30.6667003631592, -35.1730995178223, 
-48.1591987609863, -48.377498626709, -45.4000015258789, -45.7832984924316, 
-29.94580078125, -38.8652992248535, -30.4386005401611, -31.6646995544434, 
-51.2000007629395, -51.3328018188477, -51.25, -45.5666999816895, 
-45.551700592041, -45.8372001647949, -39.0144004821777, -28.9414005279541, 
-28.7502994537354, -38.6081008911133, -34.9844017028809, -32.8403015136719, 
-29.9953002929688, -18.3999996185303, -35.9000015258789, -35.6169013977051, 
-35.9085998535156, -35.8166999816895, -33.7346992492676, -45.38330078125, 
-35.4068984985352, -32.7571983337402, -32.8502998352051, -33.5938987731934, 
-36.8386001586914, -33.4961013793945, -20.1119003295898, -27.8043994903564, 
-37.7332992553711, -30.9986000061035, -30.8006000518799, -21.9368991851807, 
-22.3652992248535, -22.273099899292, -22.0277996063232, -21.9755992889404, 
-22.289400100708, -22.2791996002197, -38.4303016662598, -38.6866989135742, 
-45.4057998657227, -38.7799987792969, -37.5503005981445, -37.6018981933594, 
-37.8997001647949, -38.0368995666504, -37.9897003173828, -37.7047004699707, 
-37.7963981628418, -37.7092018127441, -31.5835990905762, -27.3635997772217, 
-27.3194007873535, -29.8931007385254, -30.9242000579834, -21.4246997833252, 
-36.5703010559082, -38.2008018493652, -38.0661010742188, -38.4333000183105, 
-31.7422008514404, -31.6881008148193, -31.8117008209229, -31.7714004516602, 
-27.86669921875, -27.5160999298096, -27.9747009277344, -30.7047004699707, 
-36.8499984741211, -36.6500015258789, -36.86669921875, -35.3736000061035, 
-40.5167007446289, -33.4782981872559, -33.198299407959, -36.0499992370605, 
-35.9667015075684, -36.2332992553711, -34.4921989440918, -34.6581001281738, 
-32.8166999816895, -47.3499984741211, -47.5, -29.9811000823975, 
-32.4413986206055, -22.3922004699707, -22.3430995941162, -21.7124996185303, 
-22.4582996368408, -22.4419002532959, -22.4468994140625, -22.5060997009277, 
-33.7219009399414, -33.6613998413086, -35.5574989318848), longitud = c(-71.0500030517578, 
-73.2166976928711, -72.38330078125, -71.371696472168, -72.8000030517578, 
-72.9666976928711, -72.1074981689453, -71.0864028930664, -72.7257995605469, 
-72.4891967773438, -68.7975006103516, -72.3242034912109, -70.3572006225586, 
-71.9847030639648, -71.7332992553711, -71.5255966186523, -69.0466995239258, 
-69.331901550293, -72.6911010742188, -72.7166976928711, -71.8082962036133, 
-71.5477981567383, -71.1782989501953, -70.5500030517578, -71.0064010620117, 
-70.6464004516602, -70.5066986083984, -71.1714019775391, -71.5333023071289, 
-71.0911026000977, -73.0888977050781, -72.9589004516602, -72.5999984741211, 
-72.61669921875, -70.5327987670898, -71.7335968017578, -71.002197265625, 
-71.2546997070312, -72.9332962036133, -73.1091995239258, -72.5167007446289, 
-72.0832977294922, -72.0680999755859, -71.7769012451172, -73.0828018188477, 
-70.2481002807617, -70.4828033447266, -72.8478012084961, -72.0100021362305, 
-71.0255966186523, -70.5867004394531, -70.3000030517578, -71.5167007446289, 
-71.7677993774414, -71.2981033325195, -71.8332977294922, -70.3007965087891, 
-72.4666976928711, -72.2082977294922, -70.736701965332, -70.5093994140625, 
-70.3792037963867, -73.061897277832, -70.8167037963867, -68.8407974243164, 
-70.1268997192383, -72.61669921875, -71.0899963378906, -70.9697036743164, 
-68.5330963134766, -68.6418991088867, -68.1438980102539, -68.6207962036133, 
-68.6074981689453, -68.3447036743164, -68.2427978515625, -72.0105972290039, 
-72.502799987793, -72.6231002807617, -72.9468994140625, -72.5903015136719, 
-72.2782974243164, -71.6239013671875, -71.4781036376953, -71.5199966430664, 
-71.7683029174805, -71.6988983154297, -71.823600769043, -71.4606018066406, 
-70.3392028808594, -70.8380966186523, -71.2514038085938, -70.7731018066406, 
-70.053596496582, -71.5547027587891, -71.2988967895508, -71.3497009277344, 
-71.2332992553711, -71.1492004394531, -71.2658004760742, -70.9302978515625, 
-71.0639038085938, -70.0667037963867, -70.2647018432617, -69.997802734375, 
-70.9244003295898, -72.38330078125, -72.4499969482422, -72.3332977294922, 
-71.8292007446289, -73.2833023071289, -70.7172012329102, -70.8955993652344, 
-72.0832977294922, -72.0167007446289, -72, -71.3731002807617, 
-71.3019027709961, -71, -72.8499984741211, -72.9749984741211, 
-70.8981018066406, -71.3139038085938, -69.5299987792969, -69.5650024414062, 
-69.5167007446289, -68.7363967895508, -68.8886032104492, -68.8775024414062, 
-68.988899230957, -71.5550003051758, -71.3371963500977, -71.7067031860352
)), row.names = c(1L, 136L, 262L, 395L, 507L, 605L, 701L, 789L, 
868L, 996L, 1094L, 1124L, 1172L, 1218L, 61387L, 61546L, 75009L, 
87052L, 99246L, 110237L, 115091L, 125346L, 135758L, 135819L, 
144524L, 154009L, 172251L, 185024L, 192338L, 210797L, 228781L, 
228893L, 238299L, 244626L, 253673L, 274263L, 285367L, 304757L, 
316768L, 328069L, 336044L, 346167L, 351691L, 363302L, 375494L, 
385229L, 402720L, 422016L, 440373L, 451547L, 462674L, 483188L, 
491968L, 496483L, 511332L, 530494L, 546443L, 564800L, 575215L, 
586462L, 602135L, 622841L, 642834L, 657640L, 677273L, 688216L, 
706550L, 724524L, 731829L, 748442L, 748489L, 754030L, 763570L, 
776729L, 785860L, 799355L, 812606L, 832675L, 853030L, 860670L, 
878448L, 889066L, 889167L, 889273L, 889372L, 889466L, 889499L, 
889524L, 913996L, 929594L, 935459L, 953842L, 963352L, 983829L, 
991810L, 1005230L, 1005341L, 1011503L, 1022492L, 1029507L, 1047978L, 
1063655L, 1073799L, 1073936L, 1086040L, 1106251L, 1126146L, 1134776L, 
1154269L, 1170495L, 1181431L, 1192018L, 1197439L, 1212431L, 1231028L, 
1247598L, 1264197L, 1264302L, 1271900L, 1279499L, 1279618L, 1290282L, 
1309415L, 1320521L, 1320606L, 1320753L, 1320827L, 1337638L, 1344817L, 
1355030L, 1368899L, 1381979L, 1393175L), class = "data.frame")

【问题讨论】:

    标签: r maps geospatial ggmap rworldmap


    【解决方案1】:

    以下代码使用简单特征 (sf) 库来显示覆盖了提供的数据点的智利地图。边界框在参数中设置为st_crop,可以根据需要进行调整,不会扭曲地图。代码使用Admin 0 - Countries shape 文件,该文件属于公共领域,可免费使用。

    library(sf)
    library(ggplot2)
    library(dplyr);
    library(magrittr);
    
    # download world shapefile from
    # https://www.naturalearthdata.com/downloads/
    #        50m-cultural-vectors/50m-admin-0-countries-2/
    # and extract zip file
    
    world <- st_read(
        # change below line to path of extracted shape file
        'c:/path/to/ne_50m_admin_0_countries.shp' 
      );
    
    world %<>% mutate(active = NAME_EN == 'Chile'); # used to highlight Chile
    
    # convert the dataframe to a sf geometry object
    dsf <- data %>% 
        rowwise %>% 
        mutate(geometry = list(st_point(c(longitud, latitud)))) %>%
        st_as_sf(crs=st_crs(world));
    
    # plot the map
    world %>% st_crop(xmin=-90, xmax=-30, ymin=-60, ymax=-10) %>%
        ggplot() + 
        geom_sf(aes(fill=active), show.legend=F) + # world map with Chile highlighted
        geom_sf(data=dsf, color='#000000') + # point overlay
        scale_fill_manual(values=c('#aaaa66', '#ffffcc')) + # country colors
        scale_x_continuous(expand=c(0,0)) +
        scale_y_continuous(expand=c(0,0)) +
        theme_void() + # remove axis labels and gridlines
        theme(panel.background=element_rect(fill='lightblue'))
    

    输出如下所示。请注意,地图不会扭曲被裁剪的区域。


    补充说明

    sf 包提供对简单特征 (sf) 几何图形的支持。简单的功能提供了用于处理多边形和点等几何图形的工具。有一个备忘单here 提供了一个很好的概述。

    绘制底图

    从 3.0 版开始,ggplot2 提供了对简单特征几何图形可视化的原生支持。这允许我们写:

    world <- st_read(
        # change below line to path of extracted shape file
        'c:/path/to/ne_50m_admin_0_countries.shp' 
      ); 
    
     ggplot(world) + geom_sf()
    

    简单的要素对象通常存储在包含描述几何的列的数据框中。这使我们可以像这样显示智利的地图:

     ggplot(world %>% filter(NAME_EN == 'Chile')) + geom_sf()
    

    或突出显示智利的地图:

    # create new geometry of world map
    # cropped to (10°S, 60°S) and (90°W, 30°W)
    chileregion <- world %>% st_crop(
        xmin=-90, 
        xmax=-30, 
        ymin=-60, 
        ymax=-10)
    
    # show region with Chile highlighted
    ggplot(chileregion %>% 
        mutate(is.chile = factor(NAME_EN == 'Chile'))) + 
        geom_sf(aes(fill=is.chile), show.legend = F) +
        scale_fill_manual(values=c('gray', 'red'))
    

    绘制点

    我们得到一个包含两列的数据框,纬度和经度。

    为了转换成一个简单的特征,我们首先使用st_point创建一个具有给定坐标值的新点:

    dsf <- data %>% #begin with data
      rowwise %>%  # dplyr::rowwise applies mutation to each row individually
      # create a geometry column that provides the point as a geometry
      mutate(geometry = list(st_point(c(longitud, latitud))))
    

    此时,dsf 只是一个带有几何列的数据框;它还不是一个简单的特征对象。我们可以使用函数st_as_sf 从数据框中创建一个 sf 对象。为此,我们还需要提供坐标参考系统 (CRS) 以允许 ggplot 将提供的坐标投影到地图渲染上。这里我们可以提供 ESPG 4326 作为 CRS,它将 x 和 y 坐标直接映射到 lat/long:

      # call st_as_sf to convert data frame to a simple geometry object.
      dsf <- st_as_sf(crs=4326);
    

    由于dsf 现在是一个简单的几何图形,您可以这样绘制:

    > ggplot(dsf) + geom_sf()
    

    (请注意,您也可以简单地使用geom_point(data=data, aes(x=longitud, y=latitud)) 覆盖基本地图上的点,而无需先转换为 sf 对象。这在这里可以工作,因为基本地图的 CRS 也是 ESPG 4326,它映射 x 和 y直接分别到经度和纬度。但是,在对几何体应用坐标变换的一般情况下,使用geom_point 将不起作用。)

    叠加

    现在将两个点都定义为几何图形,您可以简单地叠加:

    ggplot() +
      geom_sf(data=chileregion) +
      geom_sf(data=dsf)
    

    原始答案中的最终绘图添加了一些额外的视觉美感(例如蓝色背景)以生成最终的地图输出。

    【讨论】:

    • 你能解释一下R逻辑吗?我了解数据操作/可视化逻辑,但是当我绘制dsfworld 以更好地理解它时,它给了我一个geojsonio 缺少包的错误。那么,geom_sf() 如何知道在哪里绘制来自dsf 的点?如果地图只是一张图片,你是如何将数据的纬度/经度列提供/连接到世界地图的?
    • 我在回复中添加了一些额外的解释/澄清,希望能解决您的问题。我不熟悉涉及geojsonio 的错误,但是(就其价值而言)我没有在用于生成地图的系统上安装那个特定的包。
    • 非常感谢伙计!你的解释真的很有帮助,我已经有好几天了!
    • 你知道为什么如果我在geom_sf(data=dsf, color='#000000') 中更改一个变量的颜色它就不起作用吗? (我在数据框中添加了一个变量,它完美地绘制,但如果我将其更改为 geom_sf(data=dsf, color=cluster, size=0.3),它会说“集群不存在,当它在 dsf 中时。似乎根本看不到它。跨度>
    • 您需要使用aes 功能使颜色成为一种美学。这向 ggplot 表明 cluster 表示数据中的一列而不是变量/文字:geom_sf(data=dsf, aes(color=cluster), size=0.3)。如果集群是数字,您可能需要先离散化,例如,geom_sf(data=dsf, aes(color=factor(cluster)), size=0.3)
    【解决方案2】:

    这可能会有所帮助,您可以自己尝试一下:

    world_map <- map_data("world")
    Wmap <- data %>%
              rename(x =longitud , y = latitud) %>%
              ggplot() +
              geom_polygon(aes(x = long, y = lat, group = group), data = world_map, fill = "grey21", color = "grey21") +
              geom_point(aes(x = x, y = y, color = 'red')) +
              scale_color_identity() +
              coord_fixed() +
              xlab("") +
              ylab("")
    Wmap
    Chile_map <- map_data("world", region="Chile")
    Cmap <- data %>%
              rename(x =longitud , y = latitud) %>%
              ggplot() +
              geom_polygon(aes(x = long, y = lat, group = group), data = Chile_map, fill = "grey21", color = "grey21") +
              geom_point(aes(x = x, y = y, color = 'red')) +
              scale_color_identity() +
              coord_fixed() +
              xlab("") +
              ylab("")
    
    Cmap
    dev.new()
    windows.options(width=10, height=6)
    
    vp_inset <- grid::viewport(width = 0.55, height = 0.45, x = -0.1, y = 0.60, just = c("left", "top"))
    print(Wmap)
    print(Cmap, vp = vp_inset)
    

    注意:群体审美决定了哪些案例被连接在一起形成一个多边形。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-23
      • 2017-06-12
      相关资源
      最近更新 更多