7

下午好,

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

在此处输入图像描述

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

以前的类似帖子: ggplot2 带箭头/向量的风时间序列

到目前为止,我整理的代码如下:

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

使用上面的代码,我得到以下图: 在此处输入图像描述

如您所见,该图从我希望它开始的箭头开始,但方向和终点太长,我不确定如何将其缩放为一个较短的箭头,并用颜色编码以加快速度。我非常感谢您对我如何实现这一目标的任何指导。

非常感谢,阿扬

4

4 回答 4

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") 

并且更改纵横比会使事情变得混乱:

于 2014-02-20T16:40:49.730 回答
3

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

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

如果是这样,一个缺失的部分是从极坐标转换为笛卡尔坐标。(例如,http ://www.engineeringtoolbox.com/converting-cartesian-polar-coordinates-d_1347.html )

坐标系是我还没有弄清楚的缺失部分。该图是两个坐标系的混合。箭头的起点基于(时间 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()
于 2014-02-20T16:55:30.113 回答
1

使用十进制度数计算风向。假设您希望 0 度为北(向上),请使用以下命令:

ggplot(data = dat, aes(x=datetime, y=pollutant)) + 
  geom_text(aes(angle=-wd_degrees+90), label="→")
于 2017-03-12T23:38:06.780 回答
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")

风流图

于 2019-05-21T03:18:57.703 回答