【问题标题】:How do I show the y value on tooltip while hover in ggplot2悬停在ggplot2中时如何在工具提示上显示y值
【发布时间】:2016-12-19 10:00:23
【问题描述】:

当我将鼠标放在图表中的某个点上时,我希望显示 y 值。我的情节代码如下所示:

output$graph <- renderPlot({
  p1 <- ggplot(data, aes(x= date)) + 
  geom_line(aes(y=Height, colour = "Height"), size=1) + 
  geom_point(aes(y=Height, colour = "Height", text = paste("Weight/Height:", Height)))
  plot(p1)
})

我做了一些研究,我认为aes 中的text = paste("Weight/Height:", Height) 部分可以确保文本出现。不幸的是,什么也没有出现。有谁知道我做错了什么?

【问题讨论】:

  • 我已经尝试过 plotly 但它有很多我们放弃的错误,我们有我们在工作中创建的替代开源项目github.com/Roche/ggtips 它使用相同的 ggplot 数据但使用 svg 和工具提示JS。绘图的缩放也不像绘图。

标签: r ggplot2 shiny


【解决方案1】:

不幸的是,ggplot 不是交互式的,但可以使用 plotly 包轻松“修复”。您只需将plotOutput 替换为plotlyOutput,然后使用renderPlotly 进行绘图。

示例 1:情节

library(shiny)
library(ggplot2)
library(plotly)

ui <- fluidPage(
    plotlyOutput("distPlot")
)

server <- function(input, output) {
   output$distPlot <- renderPlotly({
      ggplot(iris, aes(Sepal.Width, Petal.Width)) + 
       geom_line() + 
       geom_point()
   })
}

shinyApp(ui = ui, server = server)



示例 2:plotOutput(..., hover = "plot_hover")

尽管如此,我们不必使用任何特殊的包来将交互性引入我们的图表。我们需要的只是我们可爱闪亮的shiny!我们可以使用plotOutput 选项,例如clickhoverdblclick 来使情节具有交互性。 (See more examples in shiny gallery)

在下面的示例中,我们通过 hover = "plot_hover" 添加“悬停”,然后指定默认为 300 毫秒的延迟。

plotOutput("distPlot", hover = "plot_hover", hoverDelay = 0)

然后我们可以通过input$plot_hover 访问值并使用函数nearPoints 来显示点附近的值。

ui <- fluidPage(
  selectInput("var_y", "Y-Axis", choices = names(iris)),
  plotOutput("distPlot", hover = "plot_hover", hoverDelay = 0),
  uiOutput("dynamic")

)

server <- function(input, output) {

  output$distPlot <- renderPlot({
    req(input$var_y)
    ggplot(iris, aes_string("Sepal.Width", input$var_y)) + 
      geom_point()
  })

  output$dynamic <- renderUI({
    req(input$plot_hover) 
    verbatimTextOutput("vals")
  })

  output$vals <- renderPrint({
    hover <- input$plot_hover 
    # print(str(hover)) # list
    y <- nearPoints(iris, input$plot_hover)[input$var_y]
    req(nrow(y) != 0)
    y
  })

}
shinyApp(ui = ui, server = server)

示例 3:自定义 ggplot2 工具提示:

第二种解决方案效果很好,但是是的……我们希望做得更好!是的……我们可以做得更好! (...如果我们使用一些 javaScript 但 pssssss 不要告诉任何人!)。

library(shiny)
library(ggplot2)

ui <- fluidPage(

  tags$head(tags$style('
     #my_tooltip {
      position: absolute;
      width: 300px;
      z-index: 100;
      padding: 0;
     }
  ')),

  tags$script('
    $(document).ready(function() {
      // id of the plot
      $("#distPlot").mousemove(function(e) { 

        // ID of uiOutput
        $("#my_tooltip").show();         
        $("#my_tooltip").css({             
          top: (e.pageY + 5) + "px",             
          left: (e.pageX + 5) + "px"         
        });     
      });     
    });
  '),

  selectInput("var_y", "Y-Axis", choices = names(iris)),
  plotOutput("distPlot", hover = "plot_hover", hoverDelay = 0),
  uiOutput("my_tooltip")


)

server <- function(input, output) {


  output$distPlot <- renderPlot({
    req(input$var_y)
    ggplot(iris, aes_string("Sepal.Width", input$var_y)) + 
      geom_point()
  })

  output$my_tooltip <- renderUI({
    hover <- input$plot_hover 
    y <- nearPoints(iris, input$plot_hover)[input$var_y]
    req(nrow(y) != 0)
    verbatimTextOutput("vals")
  })

  output$vals <- renderPrint({
    hover <- input$plot_hover 
    y <- nearPoints(iris, input$plot_hover)[input$var_y]
    req(nrow(y) != 0)
    y
  })  
}
shinyApp(ui = ui, server = server)



示例 4:ggvis 和 add_tooltip:

我们也可以使用ggvis 包。这个包很棒,但是还不够成熟。

更新ggvis目前处于休眠状态:https://github.com/rstudio/ggvis#status

library(ggvis)

ui <- fluidPage(
  ggvisOutput("plot")
)

server <- function(input, output) {

  iris %>%
    ggvis(~Sepal.Width, ~Petal.Width) %>%
    layer_points() %>%
    layer_lines() %>% 
    add_tooltip(function(df) { paste0("Petal.Width: ", df$Petal.Width) }) %>%
    bind_shiny("plot")
}

shinyApp(ui = ui, server = server)

已编辑


示例 5:

在这篇文章之后,我搜索了互联网,看看它是否可以比示例 3 做得更好。我为 ggplot 找到了 this 很棒的自定义工具提示,我相信它几乎没有比这更好的了。

【讨论】:

  • 感谢您非常详细的解释!我出城几天,但我回来后会试试这个。
  • 我查看了示例 5 中的链接,代码看起来非常棒。不幸的是我得到了错误:nearPoints: not able to automatically infer 'xvar' from coordinfo。从另一篇 Stackoverflow 帖子中,我了解到它可能与我代码中的 print 函数有关。但是,我认为我需要某种打印功能,主要是因为我正在使用 for-loops 和 grid.arrange() 处理多个绘图。我会尝试找到一些答案来解决这个问题
  • 是的,问题是由p &lt;- ggplot(...) ; print(p)引起的。如果您打印没有print 函数的绘图,那么p &lt;- ggplot(...) ; p 代码可以正常工作。您可以尝试在nearPoints 中指定xvalyval。我不认为grid.arrange 需要明确的print(p)。它也适用于p。我会先运行没有函数print 的代码,看看是否一切正常
  • 感谢您的帮助!我将尝试制作一个可重现的示例(可能在新帖子中)
  • Plotly 太棒了。感谢您将其包含在您的回复中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-20
  • 2021-10-02
  • 1970-01-01
  • 2012-06-18
  • 2022-09-29
  • 1970-01-01
相关资源
最近更新 更多