簡體   English   中英

ggplot2 時間序列圖,帶有顏色編碼的風向箭頭

[英]ggplot2 time series plot with colour coded wind direction arrows

下午好,

我正在嘗試生成一個時間序列圖,箭頭顯示風向,顏色顯示風速強度。 最終,我試圖得到一個這樣的情節(只是我在網上找到的一個示例圖片):

在此處輸入圖片說明

我設法找到了一個類似的帖子(見下文),我試圖遵循,但我堅持正確顯示風向箭頭。

以前的類似帖子: 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()

使用上面的代碼,我得到以下圖:在此處輸入圖片說明

如您所見,該圖從我希望它開始的箭頭開始,但方向和終點太長,我不確定如何將其縮放為較短的箭頭,顏色編碼為速度。 我真的很感激您對我如何實現這一目標的任何指導。

非常感謝,阿揚

您上面顯示的圖沒有給出正確的方向——例如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. 箭頭的起始 x 是時間
  2. 箭頭的起始 y 是污染物
  3. 箭的長度是風速
  4. 箭頭的方向是方向
  5. 箭頭的顏色是風速

如果是這樣,一個缺失的部分是從極坐標轉換為笛卡爾坐標。 (例如, http : //www.engineeringtoolbox.com/converting-cartesian-polar-coordinates-d_1347.html

坐標系是我還沒有弄清楚的缺失部分。 該圖是兩個坐標系的混合。 箭頭的起點基於(時間 x 污染物)。 但是矢量是方向和風速的極坐標。 假設(時間 x 污染物)的縱橫比不是 1,那么來自北方的 5 節微風與來自東南方的 5 節微風的長度不同。

有兩件事需要調整。 一個是(時間 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()

使用十進制度計算風的方向。 假設您希望 0 度為北(向上),請使用以下命令:

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

我想知道有類似目標的其他人是否會發現 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")

風流圖

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM