rggplot2shinyggrepel

Plot only labels for visible dots in zoomed plot


I have an issue that I am not getting further and hope for help. I used ggplot2 for the creation of a big dotplot to see the latest values of different elements according to the weeks they have been running. I used ggrepel to make most of them visible but there are still overlaps obviously. I thought a zoomable plot in shiny would help so I can zoom in to the interesting ones and read their text / label to know which element it is. Turns out that all labels are always visible in the zoomed plot and I cannot even find the dots. How can I label only the visible dots? Thank you!

Here is the code:

ui <- fluidPage(

fluidRow(
  column(width = 6, class = "well",
         h4("Zoom here"),
         fluidRow(
           column(width = 6,
                  plotOutput("plot2", height = 500,
                             brush = brushOpts(
                               id = "plot2_brush",
                               resetOnNew = TRUE
                             )
                  )
           ),
           column(width = 6,
                  plotOutput("plot3", height = 500)
           )
         )
  )
  
)
)

server <- function(input, output) {

ranges2 <- reactiveValues(x = NULL, y = NULL)

output$plot2 <- renderPlot({
tbl2 %>%  
  ggplot(aes(x = Weeks, y = maxOpenings, group = Weeks)) +
  geom_point(color = "pink", size = 2) +
  geom_text_repel(aes(label = Element)) +
  theme_classic()
})

output$plot3 <- renderPlot({
tbl2 %>%  
  ggplot(aes(x = Weeks, y = maxOpenings, group = Weeks)) +
  geom_point(color = "pink", size = 2) +
  geom_text_repel(aes(label = Element)) +
  theme_classic() +
  coord_cartesian(xlim = ranges2$x, ylim = ranges2$y, expand = FALSE)
})

observe({
brush <- input$plot2_brush
if (!is.null(brush)) {
  ranges2$x <- c(brush$xmin, brush$xmax)
  ranges2$y <- c(brush$ymin, brush$ymax)
  
} else {
  ranges2$x <- NULL
  ranges2$y <- NULL
}
})

}

shinyApp(ui = ui, server = server)

Solution

  • I actually managed myself now. In case somebody else is looking for it. It was as simple as to tell ggrepel to not repel from the edge (via xlim = c(-Inf, Inf), ylim = c(-Inf, Inf))

    Thus:

    output$plot3 <- renderPlot({
        tbl2 %>%  
          ggplot(aes(x = Weeks, y = maxOpenings, group = Weeks)) +
          geom_point(color = "pink", size = 2) +
          geom_text_repel(aes(label = Element), xlim = c(-Inf, Inf), ylim = c(-Inf, Inf)) +
          theme_classic() +
          coord_cartesian(xlim = ranges2$x, ylim = ranges2$y, expand = FALSE)