ggplot2时间序列图,带有颜色编码的风向箭头

时间:2014-02-20 15:20:36

标签: r plot ggplot2 time-series rgraph

下午好,

我正在尝试制作一个时间序列图,箭头显示风向,并着色显示风速强度。最终我试图得到这样的情节(只是我在网上找到的一个示例图片):

enter image description here

我设法找到了一个类似的帖子(见下文),我试图遵循,但我坚持正确显示风向箭头。

上一篇类似文章: ggplot2 wind time series with arrows/vectors

我到目前为止所编制的代码如下:

require(ggplot2)
require(scales)
require(gridExtra)
require(lubridate)

dat <- data.frame(datetime = ISOdatetime(2013,08,04,0,0,0) +
                     seq(0:23)*60*60, pollutant = runif(24, 25, 75))

## create wind speed data
dat$ws <- runif(nrow(dat), 0 , 15 )

## create wind direction data
dat$wd <- runif(nrow(dat), 0 , 360 )

# define an end point for geom_segment
dat$x.end <- dat$datetime + minutes(60)

ggplot(data = dat, aes(x = datetime, y = pollutant)) +
  geom_line() +
  geom_segment(data = dat,
               size = 1,
               aes(x = datetime,
                   xend = x.end,
                   y = pollutant,
                   yend = wd),
               arrow = arrow(length = unit(0.5, "cm"))) +
  theme()

使用上面的代码我得到以下图: enter image description here

正如你所看到的那样,情节开始了我希望它开始的箭头,但方向和终点太长了,我不知道如何将它缩放成一个颜色编码为速度的较短箭头。我非常感谢您对我如何实现这一目标的任何指导。

非常感谢, 阿燕

4 个答案:

答案 0 :(得分:4)

您在上面显示的图表没有给出正确的指示 - 例如dat$wd[1]约为190°,因此如果0°对应于右侧的水平箭头,则190°会给出一个向左和向下的箭头。

要获得正确方向的箭头,您需要将风向的余弦和正弦添加到箭头的起点以定义其终点(请参阅下面的代码)。这里的难点是箭头在x和y方向上的缩放,因为(1)这些轴是完全不同的尺度,因此箭头的“长度”实际上并不意味着任何东西和(2)你的纵横比绘图设备会扭曲箭头的视觉长度。

我在下面发布了一个解决方案草图,其中我将箭头在x和y方向上的偏移量缩放了用于绘图的变量范围的10%,但是这不会产生具有统一视觉长度的矢量。在任何情况下,这些箭头的长度都没有很好地定义,因为,(a)x轴和y轴代表不同的单位,(b)改变曲线的纵横比将改变这些箭头的长度。

## arrows go from  (datetime, pollutant) to
##                 (datetime, pollutant) + scaling*(sin(wd), cos(wd))
scaling <- c(as.numeric(diff(range(dat$datetime)))*60*60, # convert to seconds 
                    diff(range(dat$pollutant)))/10
dat <- within(dat, {
    x.end <- datetime  + scaling[1] * cos(wd / 180 * pi)
    y.end <- pollutant + scaling[2] * sin(wd / 180 * pi)
})


ggplot(data = dat, aes(x = datetime, y = pollutant)) +
    geom_line() +
    geom_segment(data = dat,
                 size = 1,
                 aes(x = datetime,
                     xend = x.end,
                     y = pollutant,
                     yend = y.end,
                     colour=ws),
                 arrow = arrow(length = unit(0.1, "cm"))) +
scale_colour_gradient(low="green", high="red") 

改变宽高比有点混淆:

答案 1 :(得分:3)

这还不完整,但我希望这对您或其他人来说都是一个开始。我能正确理解以下内容吗?

  1. 箭头的起始x是时间
  2. 箭头的起点是污染物
  3. 箭头的长度是windspeed
  4. 箭头的方向是方向
  5. 箭头的颜色是风速
  6. 如果是这样,一个缺失的部分是从极坐标转换为笛卡尔坐标。 (例如,http://www.engineeringtoolbox.com/converting-cartesian-polar-coordinates-d_1347.html

    坐标系是我遗漏的缺失部分。该图是两个坐标系的混合。箭头的起点基于(时间x污染物)。但是矢量是方向和风速的极坐标。假设(时间x污染物)的长宽比不是1,那么来自北方的5knot微风将具有与来自东南方的5knot微风不同的长度。

    必须调整两件事。一个是(时间x污染物)纵横比。另一个是图的物理尺寸。我不知道如何处理第二个,所以我把它固定为一个恒定的值。但是想象一下你会想要一些更好的方法 - 可能是通过查询一些底层的网格属性。

    dat <- data.frame(
    datetime = 0:100, 
    #datetime = ISOdatetime(2013,08,04,0,0,0) + seq(0:23)*60*60, 
    pollutant = 0 #Swap the next two lines for a nonuniform pollutant
    #pollutant = runif(24, 25, 75)
    )
    ## convert to a numeric variable
    # dat$datetime <- 0
    # dat$datetime <- as.numeric(dat$datetime)
    
    #Adjust the aspect ratio
    #   xrange <- range(dat$datetime)
    xlimits <- c(-5, 100)
    xrange <- diff(range(xlimits))
    ylimits <- c(-5, 10)
    yrange <- diff(range(ylimits))
    aspectratio <- xrange/yrange
    
    ## create wind speed data
    dat$ws <- 1
    #   dat$ws <- runif(nrow(dat), 0, 15)
    
    ## create wind direction data
    #dat$wd_degrees <- runif(nrow(dat), 0, 360)
    dat$wd_degrees <- seq(from=0, to=360, length.out=nrow(dat))
    dat$wd_radians <- dat$wd_degrees * (pi/180)  
    
    
    ## convert from polar to cartesian
    dat$xend <- aspectratio * (dat$ws * sin(dat$wd_radians)) + dat$datetime
    dat$yend <- aspectratio * (dat$ws * cos(dat$wd_radians)) + dat$pollutant
    
    ggplot(data = dat, aes(x = datetime, y = pollutant)) +
    geom_line() +
    geom_segment(data = dat,          
                 size = 1,
                 aes(xend = xend,
                     yend = yend,
                     color = ws),
                 arrow = arrow(length = unit(0.5, "cm"))) +
    coord_fixed(xlim=xlimits, ylim=ylimits, ratio=1) +
    theme()
    

答案 2 :(得分:0)

使用十进制度计算风的方向。假设您希望0度为北(向上),请使用以下内容:

ggplot(data = dat, aes(x=datetime, y=pollutant)) + 
  geom_text(aes(angle=-wd_degrees+90), label="→")

答案 3 :(得分:0)

我想知道其他目标相似的人是否会发现OpenAir中的以下功能有用。它基本上完全按照问题的要求进行操作,唯一的例外是它没有专门使用ggplot2(在标题中提到但并未真正指定为问题的要求)。我花了很多时间寻找一个简单的解决方案,最终偶然发现了OpenAir的“风向图”,早在2015年在以下时事通讯中宣布:

https://rstudio-pubs-static.s3.amazonaws.com/94224_992de57be72e455e8ce13386dfd9a932.html

示例代码:

library(dplyr)
library(lubridate)
library(openair)

# using the data from the question above:

dat <- data.frame(date = ISOdatetime(2013,08,04,0,0,0) +
                    seq(0:23)*60*60, pollutant = runif(24, 25, 75))
## create wind speed data
dat$ws <- runif(nrow(dat), 0 , 15 )

## create wind direction data
dat$wd <- runif(nrow(dat), 0 , 360 )


timePlot(dat, pollutant = "pollutant", 
         windflow = list(scale = 0.1, lwd = 2, col = "orange"), 
         lwd = 3, group = FALSE, 
         ylab = "Concentration")

windflow plot