10

From meteorological data (hourly values of temperature, wind and humidity) I managed to plot time series of wind speed and direction. Now I would like to add wind vectors on the time series plot. Here you can see the output I would like (arrows drawn over the actual plot).

enter image description here

I am using ggplot2, been looking through stackoverflow, ggplot2 package docs (will continue) but no solution found. Any idea or indication where to look would be a starting point.

Thanks in advance

EDIT QUESTION As suggested in a comment by @slowlearner I add here code and data to make a reproducible example. It looks like geom_segment could do the trick. I managed to calculate yend in geom_segment but can't figure out how to find xend as x axis is a time axis. I've got wind speed and direction data so I can calculate x,y wind components for geom_segment but x needs to be converted to time format.

Here is the code used for the plot (temperature) and data

for (i in 1:2 ) {

rams=subset(data,data$stat_id %in% i)
tore=subset(torre,torre$stat_id %in% i)

# Gràfica en ggplot

# Gráfica de evolución temporal de las estaciones de la zona

gtitol=places$nom[places$stat_id == i]

myplot=ggplot(data=rams,aes(x=datetime, y=tempc, colour="RAMS")) +
  geom_line()  +  ylab("Temperatura (ºC)") + xlab(" ") + 
  ggtitle(gtitol) + theme(legend.title=element_blank()) + theme(legend.position="bottom") +
  scale_y_continuous(limits = c(0,40)) +
  geom_line(data=tore,aes(x=datetime,y=temp,colour = "Torre")) 
#scale_y_continuous(breaks = round(seq(min(data$tempc), max(data$tempc), by = 2),0))


ggsave(myplot,filename=paste("RAMS-",i,".png",sep=""),width=7.78,height=5.79)

}

Following geom_segment docs I tried

p=ggplot(tore, aes(x =datetime, y = 5))
p + geom_segment(aes(xend = datetime, yend = 5 + v), arrow = arrow(length = unit(0.1,"cm")))

Getting this kind of figure. You can see x coordinate is datetime, how should I convert wind component to get xend? By now xend equals datetime but I would like something like "datetime + xwindcomp"

enter image description here

Thanks for your help

pacomet
  • 5,011
  • 12
  • 59
  • 111
  • 2
    See `geom_segment` and note that it has an `arrow` argument. – joran Aug 07 '13 at 12:55
  • 1
    check out calenderPlot() from the open air package, it might be of some help, even though it does not make time series. – eliavs Aug 07 '13 at 12:55
  • 1
    `geom_segment( aes(x = 0, y = 0, xend = xend, yend = 0), line, arrow = arrow(type = "closed", angle = 23), colour = "red", size = 1.0)` is what I use to draw an arrow in a ggplot graph. Is that what you need to know? Btw: `arrow` is a function in the `grid` package. – ROLO Aug 07 '13 at 12:55
  • Hi and thanks joran and @rolo Maybe geom_segment is useful for me. My data are wind speed and direction, which I can convert to x,y components. I can easily set yend to a fixed value plus y component. But can't get the point to set xend as axis data is time value, don't know how to convert x component to n minutes so xend is computed. – pacomet Aug 08 '13 at 07:22
  • Hi @eliavs Open air looks interesting. I'm gonna try that package. Thanks. – pacomet Aug 08 '13 at 07:28
  • I would keep it in `ggplot2` if you can as it's a rich ecology with lots of support available. Maybe you should ask a separate question (with [reproducible code and data](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example)) about the `xend` issue above; resolve that and you can use `geom_segment` for the arrows. – SlowLearner Aug 08 '13 at 07:35
  • also check out `stat_spoke` – mitchus Aug 08 '13 at 13:45
  • Hi @mitchus Nice suggestion but I can't get the point, still trying. I try `ggplot(tore, aes(x=datetime, y=5)) + stat_spoke(aes(angle=tore$dir), radius = tore$vel)` but get the same plot as before, just vertical arrows where they should be rotated by tore$dir (wind direction). Continue looking for an stat_spoke example as it looks this is a good way to do what I need. Thanks – pacomet Aug 09 '13 at 07:57
  • 2
    I'm a quite late to the party, but `oce.plot.sticks` from the oce package is designed to make this sort of graph. Might be worth investigating. – thisislammers Mar 07 '18 at 19:43

2 Answers2

4

Just as a preamble, please make sure you include all code and relevant data in future questions. If you look at your question above, you will see that some objects such as torre are not defined. That means we can't copy and paste into our R setups. Also the data to which you linked could not be used with the code in the question as it was a limited subset. My advice: (a) create fake data that looks like the data you are using (b) keep your code to the absolute minimum (c) test and double-check code and data in a new R session before you post.

As far as I can tell you want something like the below. Of course you will have to adapt it for your own purposes, but it should give you some ideas on how to tackle your problem. Notice most of the cosmetic properties such as line colours, thicknesses, legends and titles have been omitted from the plot: they are not important for the purposes of this question. EDIT Another approach might be to use the same data frame for the wind data and then use a faceting variable to show the speed in a different but linked plot.

require(ggplot2)
require(scales)
require(gridExtra)
require(lubridate)
set.seed(1234)

# create fake data for temperature
mydf <- data.frame(datetime = ISOdatetime(2013,08,04,0,0,0) +
                   seq(0:50)*10*60,
                   temp = runif(51, 15, 25))

# take a subset of temperature data,
# basically sampling every 60 minutes
wind <- mydf[minute(mydf$datetime) == 0, ]
# then create fake wind velocity data
wind$velocity <- runif(nrow(wind), -5, 20)
# define an end point for geom_segment
wind$x.end <- wind$datetime + minutes(60)

ggplot(data = mydf, aes(x = datetime, y = temp, group = 1)) +
    geom_line() +
    geom_segment(data = wind,
                 size = 3,
                 aes(x = datetime,
                     xend = x.end,
                     y = 10,
                     yend = velocity),
                 arrow = arrow(length = unit(0.5, "cm"))) +
    theme()

This generates the following plot: screenshot

SlowLearner
  • 7,907
  • 11
  • 49
  • 80
  • Thanks @slowlearner It works great, exactly what I was looking for. I'm sorry for the data, thought it was enough with the data used in the loop for plotting. Just wanted to avoid you prior data formatting commands. Try to do best next time and thanks again. – pacomet Aug 09 '13 at 10:09
3

Compute the direction of the wind using decimal degrees. Assuming that you want 0 degrees to be North (up), use the following:

ggplot(data = wind, aes(x=datetime, y=temp)) + 
  geom_text(aes(angle=-wind_dir_degrees+90), label="→")
Brian D
  • 2,570
  • 1
  • 24
  • 43
  • 1
    Are you sure that arrow should not be the orther way around? – Christiaan Jul 20 '18 at 08:09
  • 1
    This will get you an arrow that points up when angle = 0. If you want something else, you can simply alter the math in the angle aesthetic. – Brian D Jul 20 '18 at 13:15