0

Context:

I was trying to format the dates of a ggplotly to my liking (%H:%M - %a), so I found this solution and this other one suggesting the use of the text argument inside the geom_*. Essentially :

ggplot(data = input_data) +
    geom_line(aes(x      = x_variable, 
                  y      = y_variable, 
                  text   = paste('date: ', x_variable, '\n',
                                 'value: ', y_variable, '\n')
                  )
              )

ggplotly(tooltip = 'text')

But when applied, the lines vanish from the plot. This problem was solved here and also here by adding a group = 1 argument to the geom aes.

But this solution only works if there is a dataframe given to the ggplot (for it to group). If the plot is constructed from vectors, without the data argument, an error occurs:

Error in UseMethod("group_by") : 
  no applicable method for 'group_by' applied to an object of class "waiver"

Question:

Is there a way to avoid the geom to vanish when the text argument is used in a ggplotly constructed from vectors ?

Code

A minimal working example, presenting the steps described above follows:

library(ggplot2)
library(plotly)
library(scales)
library(tibble)

x_dates <- seq(
  from = as.POSIXct("1970-01-01", tz = "UTC"),
  by = "min",
  length.out = 1440
)

set.seed(42)
y_vals <- rnorm(length((x_dates)))

# Starting plot constructed from vectors, no "text" aesthetic
p1 <- ggplot() +
  geom_line(aes(x = x_dates, y = y_vals))  +
  labs(x = "Time - day",
       y = "Value") +
  scale_y_continuous(breaks = seq(-4, 4, by = 1),
                     limits = c(-4, 4)) +
  scale_x_datetime(
    date_breaks = "9 hours",
    labels = date_format("%H:%M - %a"),
    date_minor_breaks = waiver(),
  ) +
  theme(axis.text.x = element_text(
    angle = 25,
    vjust = 1.0,
    hjust = 1.0
  ))
ggplotly(p1)

# When the "text" aesthetic is added, it works but the plot vanishes.
# Solutions found in SO (group = 1) does not work. Maybe because there is no dataframe ?
p2 <- ggplot() +
  geom_line(aes(
    x = x_dates,
    y = y_vals,
    text = paste('When: ',
                 format(x_dates, '%H:%M - %a'),
                 '\n',
                 'Value: ',
                 y_vals),
    group = 1
  ))  +
  labs(x = "Time - day",
       y = "Value") +
  scale_y_continuous(breaks = seq(-4, 4, by = 1),
                     limits = c(-4, 4)) +
  scale_x_datetime(
    date_breaks = "9 hours",
    labels = date_format("%H:%M - %a"),
    date_minor_breaks = waiver(),
  ) +
  theme(axis.text.x = element_text(
    angle = 25,
    vjust = 1.0,
    hjust = 1.0
  ))
ggplotly(p2, tooltip = "text")

# Using a dataframe, it works, so group = 1 solves the (new) problem
df <- tibble("x_dates" = x_dates, "y_vals" = y_vals)

p3 <- ggplot(data = df) +
  geom_line(aes(
    x = x_dates,
    y = y_vals,
    text = paste('When: ',
                 format(x_dates, '%H:%M - %a'),
                 '\n',
                 'Value: ',
                 y_vals),
    group = 1
  ))  +
  labs(x = "Time - day",
       y = "Value") +
  scale_y_continuous(breaks = seq(-4, 4, by = 1),
                     limits = c(-4, 4)) +
  scale_x_datetime(
    date_breaks = "9 hours",
    labels = date_format("%H:%M - %a"),
    date_minor_breaks = waiver(),
  ) +
  theme(axis.text.x = element_text(
    angle = 25,
    vjust = 1.0,
    hjust = 1.0
  ))
ggplotly(p3, tooltip = "text")
symduk
  • 33
  • 1
  • 6

0 Answers0