ggplot2中使用paste0函数的文本美感会更改geom_bar填充顺序;如何解决?

时间:2019-07-10 12:37:56

标签: r ggplot2 plotly geom-bar

我正在尝试制作一个堆叠的条形图,将一个变量映射为log10刻度。我想将其通过ggplotly,以便可以通过工具提示进行数据检查。

有两个问题。首先,当我在scale_fill_gradientn中对VAR.B的比例进行对数转换时,工具提示显示转换后的数据,而图形以其原始比例显示数据,这无济于事。

但是,当我在ggplot中包含美学文字来解决此问题时,它将破坏填充的顺序。我还没有找到解决这两个问题的方法。

我已经尝试过log10在数据帧本身中转换VAR.B。在这种情况下,工具提示将与显示的数据匹配,但是我认为这对于我的受众而言并不容易实现。另外,将数据集保持线性比例会丢失故事的重要部分。

数据集

a<-structure(list(VAR.A = c("A", "A", "A", "A", "A", "A", "A", "A", 
"A", "A", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B"), 
    VAR.B = c(1, 2, 3, 5, 8, 9, 10, 12, 13, 15, 1, 10, 30, 35, 
    40, 60, 80, 100, 140, 160), rel.freq = c(3.076923077, 4.615384615, 
    7.692307692, 12.30769231, 15.38461538, 6.153846154, 30.76923077, 
    3.076923077, 7.692307692, 9.230769231, 1.754385965, 3.50877193, 
    26.31578947, 1.754385965, 17.54385965, 35.0877193, 3.50877193, 
    5.263157895, 3.50877193, 1.754385965)), class = c("spec_tbl_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -20L), spec = structure(list(
    cols = list(VAR.A = structure(list(), class = c("collector_character", 
    "collector")), VAR.B = structure(list(), class = c("collector_double", 
    "collector")), counts = structure(list(), class = c("collector_double", 
    "collector")), rel.freq = structure(list(), class = c("collector_double", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
    "collector")), skip = 1), class = "col_spec"))

依赖项

library(ggplot2)
library(viridis)
library(plotly)
library(scales)

此图看起来应该看起来像,但是VAR.B悬停文本中显示的值与原始比例不匹配

f <- ggplot(a, aes(x=VAR.A, y= rel.freq, fill = VAR.B)) + 
  geom_bar(width = 1, size = 1, stat = "identity") + 
  scale_fill_gradientn(colors = viridis(10, option = 'inferno'), limits = c(0.1, 160), breaks = c(0.1,0.3, 1, 3, 10, 30, 100), 
                       trans = "log10", guide = guide_colorbar(draw.llim = FALSE, draw.ulim = FALSE), oob = squish) +
  theme_classic()

f<- ggplotly(f)
f

此图看起来很混乱,但是VAR.B悬停文本中显示的值确实与原始比例匹配。

g <- ggplot(a, aes(x=VAR.A, y= rel.freq, fill = VAR.B, text = paste0('VAR.B:', VAR.B))) + geom_bar(width = 1, size = 1, stat = "identity") + 
  scale_fill_gradientn(colors = viridis(10, option = 'inferno'), limits = c(0.1, 160), breaks = c(0.1,0.3, 1, 3, 10, 30, 100), 
                       trans = "log10", guide = guide_colorbar(draw.llim = FALSE, draw.ulim = FALSE), oob = squish) +
  theme_classic()

g <- ggplotly(g, tooltip = c('VAR.A','VAR.B','text'))
g

如果我不希望在粘贴文字时使用paste0()函数,而只调用VAR.B本身,那么工具提示将以原始比例显示数据,并保留填充顺序。但是在这种情况下,工具提示没有为数据提供标签。

h <- ggplot(a, aes(x=VAR.A, y= rel.freq, fill = VAR.B, text = VAR.B)) + 
  geom_bar(width = 1, size = 1, stat = "identity") + 
  scale_fill_gradientn(colors = viridis(10, option = 'inferno'), limits = c(0.1, 160), breaks = c(0.1,0.3, 1, 3, 10, 30, 100), 
                       trans = "log10", guide = guide_colorbar(draw.llim = FALSE, draw.ulim = FALSE), oob = squish) +
  theme_classic()

h <- ggplotly(h, tooltip = c('VAR.A','VAR.B','text'))
h

在我看来,文本美学中的paste0()函数存在错误。如果有人能想到立即解决所有这些问题的另一种方法,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

之所以会这样,是因为text = paste0('VAR.B:', VAR.B)))创建了一个因子,该因子按字母顺序排序。

i <- ggplot(a, aes(x=VAR.A, y= rel.freq, fill = VAR.B, 
                   text = factor(paste0('VAR.Bt:', VAR.B)[order(VAR.A,VAR.B)],
                                 levels=unique(paste0('VAR.Bt:', VAR.B)[order(VAR.A,VAR.B)]),
                                 ordered = T) #makes the factor specifically ordered
                   )
            ) + 
  geom_bar(width = 1, size = 1, stat = "identity",
    position = position_stack(reverse = T) #has to be reversed, so high values of VAR.B appear on top
            ) +
  scale_fill_gradientn(colors = viridis(10, option = 'inferno'), 
                       limits = c(0.1, 160),
                       breaks = c(0.1,0.3, 1, 3, 10, 30, 100), 
                       trans = "log10", 
                       guide = guide_colorbar(draw.llim = FALSE, draw.ulim = FALSE), 
                       oob = squish) +
  theme_classic()

i <- ggplotly(i, tooltip = c('VAR.A','VAR.B','text'))
i

希望这会有所帮助:-) 我编辑了t,所以很明显哪个调用产生了什么