How to add text label to multiple vertical lines automatically based on values from user-specified data subset (via Shiny)

Viewed 43

Data and and an example of the final plot below:

df <- data.frame(player = c("A", "A", "A", "A", "A", "A", "A", "A", "A", "A",
                        "B", "B", "B", "B", "B", "B", "B", "B", "B", "B",
                        "C", "C", "C","C", "C", "C", "C","C", "C", "C"),
                 year = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
                            1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
                            1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
                 statistic = c(.5, .6, .8, .4, .9, .8, .8, .7, .7, .8,
                            .3, .4, .5, .4, .7, .4, .8, .7, .7, .8,
                            .6, .6, .7, .6, .6, .8, .8, .7, .7, .8),
                 change_team = c(0, 0, 0, 1, 0, 0, 0, 1, 0, 0,
                                 0, 0, 1, 1, 0, 0, 1, 0, 0, 1,
                                 0, 0, 0, 0, 0, 1, 1, 0, 0, 0),
                 team = c("CHI", "CHI", "CHI", "CLE", "CLE", "CLE", "CLE", "DET", "DET", "DET",
                          "BOS", "BOS", "PHI", "DAL", "DAL", "DAL", "HOU", "HOU", "HOU", "MIA",
                          "ORL", "ORL", "ORL", "ORL", "ORL", "DEN", "MIN", "MIN", "MIN", "MIN"))

selection <- "A"

df2 <- df %>%
  filter(player == selection)

vlines <- df2$year[df2$change_team == 1]

ggplot(data = df2, aes(year, statistic)) +
  geom_point() +
  geom_line() +
  geom_vline(xintercept = vlines, linetype = "dashed") +
  geom_label(aes(4,.95), label = "CLE", show.legend = F) +
  geom_label(aes(8,.95), label = "DET", show.legend = F) +
  scale_x_continuous(breaks = seq(1, 10, 1)) +
  ggtitle("Placeholder Title")

link to example plot

I'm making a Shiny app that will allow the user to specify which player they want to analyze. For whichever player is selected, I would like vertical lines for the year in which the player is on a new team (denoted by 1 in the change_team variable). This I have figured out how to do automatically for any player selected. The part I don't have figured out is adding labels to the vertical lines with the corresponding value of the team variable (shown as "CHI" and "DET" on the plot).

How do I ensure that the label will be in the proper location for any player selected in the app, especially considering each player will have a different range of statistic values (I'd like the label to be at/near the top of each vertical line), and each player will have different line positions as well as number of vertical lines to label?

1 Answers

This could be achieved like so:

  1. Filter you dataset by change_team
  2. Use this filtered df as data for both the geom_vline and the geom_label
  3. For the geom_label you could use the max value of statistic + some nudging to put it at the top.

library(ggplot2)
library(dplyr)

df2 <- df %>%
  filter(player == selection)

change_team <- filter(df2, change_team == 1)

ggplot(data = df2, aes(year, statistic)) +
  geom_point() +
  geom_line() +
  geom_vline(data = change_team, aes(xintercept = year), linetype = "dashed") +
  geom_label(data = change_team, aes(y = max(df2$statistic) + .05, label = team), show.legend = F) +
  scale_x_continuous(breaks = seq(1, 10, 1)) +
  ggtitle("Placeholder Title")

Related