为具有多个 aes() 的绘图设置工具提示文本

Set tooltip text for plot with more than one aes()

在下面的 ggplot 中,我尝试使用 ggplotly() 工具提示作为文本来更改点和列中的悬停文本,但我无法更改它。另外,由于我对每个 aes() 使用 2 texttooltip 如何知道我传递给它的是哪一个?

library(ggplot2)
library(plotly)
dt2<-structure(list(year2 = c(1950, 1955, 1960, 1965, 1970, 1975, 
1980, 1985, 1990, 1995, 2000, 2005, 2010, 2015), pta_count = c(2, 
4, 10, 14, 24, 18, 13, 19, 84, 100, 105, 96, 47, 15), scope_ntis_mean = c(3.5, 
9.5, 5, 9.57142857142857, 4.54166666666667, 11.7222222222222, 
6.23076923076923, 7.05263157894737, 17.1071428571429, 15.16, 
15.2761904761905, 17.6354166666667, 22.9574468085106, 26.8666666666667
), scope_ntis_sd = c(0.707106781186548, 11.7046999107196, 6.25388767976457, 
8.72409824049971, 4.56812364359683, 9.2278705436976, 5.11784209333462, 
10.7779284971676, 13.2864799994027, 12.9643801053175, 12.1295056958191, 
12.7964796077233, 12.4375963125981, 14.5791762782532), scope_ntis_se = c(0.822426813475736, 
9.62625905026287, 3.25294959458435, 3.83516264302846, 1.53376734188638, 
3.57760589505535, 2.33476117415722, 4.06710846230115, 2.38450123589789, 
2.13245076374089, 1.94704374916827, 2.14823678655809, 2.98410970181292, 
6.19176713030084), scope_ntis_cil = c(2.67757318652426, -0.12625905026287, 
1.74705040541565, 5.73626592840011, 3.00789932478029, 8.14461632716687, 
3.89600805661201, 2.98552311664622, 14.722641621245, 13.0275492362591, 
13.3291467270222, 15.4871798801086, 19.9733371066977, 20.6748995363658
), scope_ntis_ciu = c(4.32242681347574, 19.1262590502629, 8.25294959458435, 
13.406591214457, 6.07543400855305, 15.2998281172776, 8.56553040492645, 
11.1197400412485, 19.4916440930407, 17.2924507637409, 17.2232342253587, 
19.7836534532248, 25.9415565103236, 33.0584337969675)), row.names = c(NA, 
-14L), class = c("tbl_df", "tbl", "data.frame"))

p<-ggplot(dt2, aes(x=year2)) + 
      
      geom_col(aes(y=pta_count/(max(dt2$pta_count)/max(dt2$scope_ntis_ciu)),
                   text = paste(
                     "Year :",
                     ~year2,
                     "<br> Count of issues :",
                     ~pta_count/(max(dt2$pta_count)/max(dt2$scope_ntis_ciu))
                   )),
               fill="darkolivegreen",alpha=0.3,width=3)+
      geom_point(aes(y=scope_ntis_mean,
                     text = paste(
                       "Year :",
                       ~year2,
                       "<br> Count of issues :",
                       ~scope_ntis_mean
                     )))+
      geom_segment(aes(x=year2,y=scope_ntis_cil,xend=year2,yend=scope_ntis_ciu
                       ),
                   arrow=arrow(length=unit(0.1,"cm"),
                               ends='both'),
                   lineend="square",size=0.3) +
      scale_x_continuous(n.breaks=14)+
      # Custom the Y scales:
      scale_y_continuous(
        
        # Features of the first axis
        name = "NTI Scope\n(scope measures the sum of all NTIs mentioned in a PTA,\ndot indicated mean scope per 5-year interval,\n arrows signal confidence intervals)",
        
        # Add a second axis and specify its features
        sec.axis = sec_axis( ~ . * max(dt2$pta_count)/max(dt2$scope_ntis_ciu), name="PTA Count\n(green columns indicate number of PTAs\n signed in given 5-year intervall)")
      )+
      labs(x='')+
      theme_bw()+theme(axis.title = element_text(size = 8),
                       axis.title.y = element_text(margin = margin(t = 0, r = 20, b = 0, l = 0)))
    
    ggplotly(p,tooltip = "text")

因为你给我发了关于你上一个问题的评论,所以我从两个角度来看了这个问题。我不断收到此代码的错误。我不会专注于解决这些问题,而是向您展示如何自定义工具提示,而无需先创建 ggplotly 对象,并且当您已经创建(如上一个问题)时。

  1. ggplot 对象开始
  2. ggplotlyplotly 对象开始

1)

由于您只是修改仍然代表 x- 和 y-axes 的工具提示,我认为这是最简单的方法。我使用 tidyverse 中的 stringr 来修改工具提示。

library(tidyverse) 

# create plotly object to modify
p2 <- plotly_build(p)

# now modify the text calls for each trace that this applies to

# modfiy existing tooltips
# this is the first trace (the bar chart or first geom in ggplot object)
p2$x$data[[1]]$text <- str_replace_all(p2$x$data[[1]]$text, 
                                       "year2", "Year ") %>% 
  str_replace_all(., fixed("pta_count/(max(pta_count)/max(scope_ntis_ciu))"),
                  "Count of issues ")

# validate change
p2$x$data[[1]]$text # looks right

# now for the second trace
p2$x$data[[2]]$text <- str_replace_all(
  p2$x$data[[2]]$text, "year2", "Year ") %>% 
  str_replace_all(., "scope_ntis_mean", "Count of issues ")

# validate change
p2$x$data[[2]]$text # looks right

2)

首先我将hoverinfo = "skip"添加到不可见的痕迹中。然后我将那个 ggplotly 对象的构建分配给一个对象名称。请记住,这是使用您上一个问题中的对象 p 的版本。

p2 <- ggplotly(p) %>% 
  add_trace(inherit = F, x = ~year2,
            y = ~(pta_count/(max(pta_count)/ max(scope_ntis_ciu))
            ) * (max(dt2$pta_count)/max(dt2$scope_ntis_ciu)),
            data = dt2, 
            yaxis = "y2", 
            hoverinfo = "skip",               # NO TOOLTIPS!
            alpha = 0,                        # make it invisible
            type = "bar") %>% 
  layout(margin = list(l = 85, r = 85),
         yaxis2 = list(
           ticklen = 3.7,                     # to match other axes
           tickcolor = "rgba(51, 51, 51, 1)", # to match other axes
           tickfont = list(size = 11.7,       # to match other axes
                           color = "rgba(77, 77, 77, 1)"), # to match the others
           titlefont = list(size = 11.7),     # to match other axes
           side = "right",
           overlaying = "y",
           showgrid = F,      # to match ggplot version
           dtick = 25,        # between ticks
           title = "PTA Count\n(green columns indicate number of PTAs\n signed in given 5-year interval)"))


p2$x$data[[1]]$text <- str_replace_all(
  p2$x$data[[1]]$text, "year2", "Year ") %>% 
  str_replace_all(., fixed("pta_count/(max(pta_count)/max(scope_ntis_ciu))"),
                  "Count of issues ")
# validate
p2$x$data[[1]]$text

# now for the second trace
p2$x$data[[2]]$text <- str_replace_all(
  p2$x$data[[2]]$text, "year2", "Year ") %>% 
  str_replace_all(., "scope_ntis_mean", "Count of issues ")
# validate
p2$x$data[[2]]$text

本质上,plotly_buildggplotly 创建相同的对象。在 1 和 2 中,p2 已准备好被调用。