Good afternoon,
I am trying to produce a time-series plot with arrows showing wind direction and coloured to show wind speed strength. Ultimately I am trying to get a plot something like this (just an example picture I found online):
I have managed to find a similar post (see below) and I tried to follow but I am stuck with the displaying of Wind Direction arrows correctly.
Previous similar post: ggplot2 wind time series with arrows/vectors
The codes I have put together so far are as follows:
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()
Using the above code I am getting the following plot:
As you can see the plot starts the arrow where I would like it to start but the direction and end point is too long and I am not sure how I can scale this to be a shorter arrow with colour coded to speed. I would really appreciate any of your guidence regarding how I can acheive this.
Many thanks, Ayan
The plot you show above does not give the correct directions -- e.g. dat$wd[1]
is about 190° , so if 0° corresponds to a horizontal arrow to the right, 190° should give you an arrow pointing left and slightly down.
To get arrows with the right direction, you need to add the cosine and sinus of the wind direction to the starting point of your arrow to define its endpoint (see code below). The difficult issue here is the scaling of the arrow in x- and y-direction because (1) these axes are on completely different scales, so the "length" of the arrow cannot really mean anything and (2) the aspect ratio of your plotting device will distort the visual lengths of the arrows.
I've posted a solution sketch below where I scale the offset of the arrow in x and y direction by 10% of the range of the variables used for plotting, but this does not yield vectors of uniform visual length. In any case, the length of these arrows is not well defined, because, again, (a) the x- and y-axes represent different units and (b) changing the aspect ratio of the plot will change the lengths of these arrows.
## 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")