0

I have a multi-line chart created using ggplot2 with autoplot and plotly in R code. I would like to add a single point on each line on the chart. The data frame I am plotting is of class xts. In the toy example below, I would like to add a point at 2019-12-22 on the "aa" line (red) and at 2019-12-24 on the "bb" line (blue). The dates for the points are in a named vector, 'my_points'. How do I do this??

library("xts")
library("ggplot2")
library("plotly")

my_dates <- as.Date(18250:18256)
## My points are in a named vector ...
my_points <- c(my_dates[3], my_dates[5])
names(my_points) <- c("aa", "bb")

## The toy data for the example created as an xts object
my_df <- data.frame(aa = c(14,12,23,14,15,26,17),
                    bb = c(14.2, 16.0, 12.3, 13.8, 10.1, 9.6, 8.9))
my_xts <- xts(my_df, order.by = my_dates)

## Plotted using autoplot and plotly to make it interactive
p <- autoplot(my_xts, facets = NULL)
pl <- ggplotly(p)
print(pl)

2 Answers 2

2

Perhaps a better and more general way would have been to melt the data into the long format. There may be better ways, but this is a flexible approach that allows for many data points and numerous curves, just as the "real" problem has.

## Prepare some data ... 2 straightline plots
a <- c(14,12,23,14,15,26,17)
b <- c(14.2, 16.0, 12.3, 13.8, 10.1, 9.6, 8.9)
my_dates <- as.Date(18250:18256)
my_df <- data.frame(aa = a,
                    bb = b)
my_df1 <- as.data.frame(cbind(my_dates, my_df))
## Construct a small df for points to be plotted
plot_df2 <- data.frame(my_dates = c(my_dates[3], my_dates[5]),
                       variable = c("pp", "pp"),
                       value = c(a[3], b[5]))

## Melt the data into the long form 
plot_df1 <- melt(my_df1, id.vars = "my_dates")

## Add the point information to the plot df
plot_df1 <- rbind(plot_df1, plot_df2)

p <- ggplot(data =  subset(plot_df1, variable == c("aa", "bb")),
             aes(x = my_dates, y = value,
             color = variable, group = variable)) +
    geom_line() +
    geom_point(data = subset(plot_df1, variable == "pp"),
  aes(x = my_dates, y = value), size = 2, color = "black")

pl <- ggplotly(p)
print(pl)
Sign up to request clarification or add additional context in comments.

Comments

1

While I would not recommend overloading the convenience functions offered by autoplot and xts you can get it done as follows:

my_xts_points_aa = my_xts[my_points[1],]
my_xts_points_bb = my_xts[my_points[2],]

p <- autoplot(my_xts, facets = NULL) + 
  geom_point(data=my_xts_points_aa,aes(y=aa)) +
  geom_point(data=my_xts_points_bb,aes(y=bb))
p

My personal reservation with this solution is that it feels a little hacky/manual because of the way your data is organized in wide format (aa and bb column instead of a value column with key aa or bb). Yet, autoplot on the xts object handles this automatically and silently introduces a Series categorical variable. Still, I hope this helps - potentially there is a direct way using the autoplot-xts facilities..

1 Comment

Thank you. I'm not wedded to autopiot and I think you are saying reorganize the data and add the point data with its own key. I can experiment with that as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.