2014-02-20 127 views
6

下午好,GGPLOT2时间序列图与彩色编码风向箭头

我试图生产出的箭头显示风向和彩色显示风速强度的时间序列图。最后,我想获得一个情节是这样的(只是一个例子图片我在网上找到):

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

你看上面并没有给出正确的方向上的情节 - 例如dat$wd[1]约为190°,所以如果0°对应右侧的水平箭头,则190°应该给你一个向左和向下的箭头。要获得正确方向的箭头,需要将风向的余弦和正弦添加到箭头的起点以定义其终点(请参阅下面的代码)。因为(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") 

而改变纵横比那种混乱的事情了:

+0

嗨法比安斯,非常感谢!这回答了我的问题,我可以在此工作并建立我所需要的。非常感谢! :) – Achak

+0

很高兴帮助。我想,检查出并提出wibeasleys提案,他的代码明确地处理了宽高比。 – fabians

3

这是不完整的,但我希望这将是对你或别人一个开始。我是否正确理解以下内容?

  1. 箭头的起始x是时间
  2. 箭头的起始Y是污染物
  3. 箭头的长度是风速
  4. 箭头的方向是方向
  5. 箭头的颜色是风速

如果是这样,一个缺少的部分是从极坐标转换到笛卡尔坐标。 (例如,​​)

坐标系是我没有想到的缺失部分。该图是两个坐标系的混合。箭头的起点基于(时间x污染物)。但矢量是方向和风速的极坐标。假设(时间x污染物)的纵横比不为1,则来自北部的5节小风将具有与来自东南部的5节小风不同的长度。

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

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() 
+0

不错的一个 - 很高兴看到我们都聚合在类似的解决方案和相同的问题上。 – fabians

+0

嗨Wibeasley, 是的我试图达到你提到的5点。非常感谢您提供更多信息,我将对您今晚提到的要点进行良好的阅读和研究,以让我的头脑得到充分发挥。 )再次感谢您对此的帮助:) – Achak

0

使用十进制度计算风向。假设你想0度北(上),使用以下内容:

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