【问题标题】:R: Colour points on a map based on their value and add legendR:根据值在地图上着色并添加图例
【发布时间】:2018-07-19 20:15:58
【问题描述】:

我有一个数据集,其中包含经度、纬度和一个显示湿度的值列,长度约为 300 行。每个点显示不同位置的湿度。我想将它们全部绘制在地图上并根据它们的值(例如渐变颜色)为它们着色并添加图例。它有点类似于question here,但我无法让它工作。代码基本上就在那里,但只有在图例中正确着色和显示它并不能真正起作用。这些点代表非洲的一条线,湿度值最初是从栅格数据集中提取的,它们包含几个数字。我创建了一些示例数据来说明我卡在哪里。

library("maps")
library("raster")

# create sample data
lon <- seq(from=35.6, to=43.2, by=0.2)
lat <- seq(from=10.5, to=22.2, by=0.2)
humidity <- runif(59, min=9.6, max=13.5)
data <- data.frame(lon,lat, humidity)

colfunc<-colorRampPalette(c("dodgerblue2","khaki","orangered")) # create colours
map('world', xlim = c(20, 80), ylim = c(5, 30), lwd=0.5, col = "grey95", fill = T, interior = FALSE)
title("specific humidity along line")
map.axes()
points(data$lon, data$lat, cex=.5, pch=19, col=colfunc(100))
legend("topleft",title="q (g/kg)",legend=c(11,11.5,12,12.5,13),col =colfunc(100), pch=20)

生成的图如下所示: 图例显然有问题,我想在图例中显示一些带有相应颜色和值的点,甚至使用漂亮的颜色条。我不确定为什么图例中的颜色只是蓝色。我还怀疑点线没有根据它们的实际值着色,而只是显示整个颜色渐变。感谢您的任何建议! 使用 Alex 的代码更新:

n <- 10

colfunc<-colorRampPalette(c("dodgerblue2","khaki","orangered")) # create colours
mycol <- function(x, myrange, n=10) round( 1+(x-myrange[1])/diff(myrange) * (n-1))
map('world', xlim = c(20, 80), ylim = c(5, 30), lwd=0.5, col = "grey95", fill = T, interior = FALSE)
title("specific humidity along line")
map.axes()
points(data$lon, data$lat, cex=.5, pch=19, col=colfunc(n)[mycol(humidity, range(humidity), n)])
mylist <- c(10,11,11.5,12,12.5,13)
legend("topleft",title="q (g/kg)",legend=mylist,col = colfunc(n)[mycol(mylist,range(humidity), n)], pch=20)

生成这个情节: 点是重叠的,很难看到点的整体值,有没有办法根据定义的范围使用 colourramp 对点进行着色?比如“红色”代表值 10 到 11,“绿色”代表 11 到 12 等等?

【问题讨论】:

  • 您的代码应该生成一些示例数据。我不想下载文件,而且将来它会消失,从而使 Q 和 A 的用处大大降低。
  • 你说得对,我只是相应地更改了它并添加了示例数据。谢谢!

标签: r plot colors maps


【解决方案1】:

您可能混淆了一些事情。在您的代码中,您正在绘制点的颜色只是点顺序的结果(第一个点在列表中获得第一个颜色等)。颜色不取决于值。

现在,在整个 0:100 范围内的湿度值的颜色渐变中,坦率地说,您将看不到值 11 和 13 之间的任何差异。您需要更多的对比度。 所以你应该先做

mycol <- function(x, myrange, n=100) round( 1+(x-myrange[1])/diff(myrange) * (n-1))

现在mycol(x, range(humidity), n) 将返回一个整数,最小值为 1,最大值为 n。

n=100
points(data$lon, data$lat, cex=.5, pch=19, col=colfunc(n)[mycol(humidity, range(humidity), n)])

mylist <- c(11,11.5,12,12.5,13)
legend("topleft",title="q (g/kg)",legend=mylist,col = colfunc(n)[mycol(mylist,range(humidity), n)], pch=20)

【讨论】:

  • 非常感谢您的帮助,亚历克斯。我尝试使用您的代码,并且效果很好!湿度值不代表 0 到 100 (%) 范围内的相对湿度,而是代表特定湿度,因此我将 n=100 更改为 n=10,但我不确定该值是否有意义,因为特定湿度值在范围约为 10 至 13.2 g/kg?不幸的是,彩色点确实相互覆盖,有没有办法可以将特定颜色分配给 10 到 11、11 到 12 等范围?在这种情况下,这条线在地图上看起来会更平滑。
  • n 的任何值都与另一个值一样有意义,因为它只是调色板中不同颜色的数量。对于“漂亮”的间隔,您可以使用相同的 mycol 函数,但设置不同的范围,例如c(10,14),n=4。
【解决方案2】:

你可以seq图例

library("maps")
library("raster")


n <- 4 # number in legend
# create sample data
lon <- seq(from=35.6, to=43.2, by=0.2)
lat <- seq(from=10.5, to=22.2, by=0.2)
humidity <- runif(39, min=9.6, max=20)
data <- data.frame(lon,lat[1:39], humidity)

    colfunc<-colorRampPalette(c("dodgerblue2","khaki","orangered")) # create colours
    map('world', xlim = c(20, 80), ylim = c(5, 30), lwd=0.5, col = "grey95", fill = T, interior = FALSE)
title("specific humidity along line")
map.axes()
points(data$lon, data$lat, cex=.5,pch=18, col=colfunc(nrow(data)))
legend("topleft",title="q (g/kg)",legend=round(seq(min(humidity),max(humidity),length.out = n),0),col =colfunc(n), pch=20) 

【讨论】:

  • 非常感谢您的示例代码,它看起来简单明了,工作正常。然而,正如亚历克斯所指出的,这些颜色并不代表实际的湿度值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多