rggplot2ggiraph

ggiraph, ggplot2, R : How to get ifelse() to work with interactive text?


I want the text labels on the stacked bar chart to be interactive so the bar chart doesn't flicker as you move the mouse over the text. To hide labels that don't fit on the small bars, I am using label=ifelse(Result > 0.06, percent(Result), ""). However, using ifelse() brings up the following error and prevents geom_text() from becoming interactive:

Warning message:
In set_attr(name = attrName, ids = as.integer(ids), values = attrValue) :
  Failed setting attribute 'data-id', mismatched lengths of ids and values (most often, it occurs because of clipping or because of NAs in data)

If this is a bug and there's no workaround, is there still a way for me to add custom css to the text labels, like "pointer-events: none", within the below code (and not by editing the html file after it's exported)?

The code:

library(ggplot2)
library(ggiraph)
require("tidyverse")
require("scales")

Area <- c("location1", "location2", "location3", "location4")
variable1 <-  c(14, 7, 17, 16)
variable2 <-  c(33, 31, 35, 31)
variable3 <-  c(33, 36, 30, 5)
variable4 <-  c(17, 5, 14, 10)

df1 <- data.frame(
  Area, 
  variable1, 
  variable2, 
  variable3,
  variable4
)

df1_subset <- df1 %>%
  mutate_at(vars(2:5), funs(./100)) %>% 
  pivot_longer(
    cols = c(2:5),
    names_to = "Question", values_to = "Result"
  )

df1_subset <- transform(
  df1_subset,groupID=as.numeric(forcats::fct_inorder(Question))
  )

set.seed(1)

stacked_chart <- ggplot(
  data=df1_subset, 
  aes(
    x=Result,
    y=Area,
    group=Question,
    fill=Question,
    data_id=groupID
  )
) +
  geom_col_interactive(
    position = position_fill(reverse = TRUE)
  ) +
  geom_text_interactive(
    aes(
      label=ifelse(Result > 0.06, percent(Result), "")
    ), 
    col="#FFFFFF",
    fontface="bold",
    position = position_fill(
      reverse = TRUE
    ), 
    hjust = 1.3
  ) +
  scale_y_discrete(
    limits=rev(Area)
  )+
  scale_x_continuous(
    labels=scales::percent,
    expand = c(0,0),
    limits = c(0, 1)
  )+
  scale_fill_manual(
    labels=c(
      "Variable 1", 
      "Variable 2", 
      "Variable 3",
      "Variable 4"
    ), 
    values=c(
      "#000000",
      "#333333",
      "#666666",
      "#999999"
    )
  )+
  theme_minimal()+
  theme(
    legend.position = "top",
    legend.justification = "left",
    legend.title = element_blank()
  )

stacked_chart_ggiraph <- girafe(
  ggobj = stacked_chart, width_svg = 9, height_svg = 6,
  options = list(
    opts_sizing(rescale = TRUE),
    opts_toolbar(saveaspng = FALSE),
    opts_hover_inv(css = girafe_css(
      css = "opacity:0.3;"
    )
    ),
    opts_hover(css = girafe_css(
      css = "cursor:pointer;"
    ))
  )
)

stacked_chart_ggiraph

Solution

  • After all it's just a warning not an error. But a possible workaround to avoid the warning would be plot all labels but to set the color for small values to "transparent" using an ifelse and scale_color_identity:

    library(ggplot2)
    library(ggiraph)
    library(scales)
    
    stacked_chart <- ggplot(
      data = df1_subset,
      aes(
        x = Result,
        y = Area,
        group = Question,
        fill = Question,
        data_id = groupID
      )
    ) +
      geom_col_interactive(
        position = position_fill(reverse = TRUE)
      ) +
      geom_text_interactive(
        aes(
          color = ifelse(Result > 0.06,  "#FFFFFF", "transparent"),
          label = percent(Result)
        ),
        fontface = "bold",
        position = position_fill(
          reverse = TRUE
        ),
        hjust = 1.3
      ) +
      scale_y_discrete(
        limits = rev(Area)
      ) +
      scale_x_continuous(
        labels = scales::percent,
        expand = c(0, 0),
        limits = c(0, 1)
      ) +
      scale_color_identity() +
      scale_fill_manual(
        labels = c(
          "Variable 1",
          "Variable 2",
          "Variable 3",
          "Variable 4"
        ),
        values = c(
          "#000000",
          "#333333",
          "#666666",
          "#999999"
        )
      ) +
      theme_minimal() +
      theme(
        legend.position = "top",
        legend.justification = "left",
        legend.title = element_blank()
      )
    
    stacked_chart_ggiraph <- girafe(
      ggobj = stacked_chart, width_svg = 9, height_svg = 6,
      options = list(
        opts_sizing(rescale = TRUE),
        opts_toolbar(saveaspng = FALSE),
        opts_hover_inv(css = girafe_css(
          css = "opacity:0.3;"
        )),
        opts_hover(css = girafe_css(
          css = "cursor:pointer;"
        ))
      )
    )
    
    stacked_chart_ggiraph