简体   繁体   English

ggplot2 中带有 paste0 功能的文本美学改变了 geom_bar 填充顺序; 如何解决?

[英]Text aesthetic with paste0 function in ggplot2 alters geom_bar fill order; How to fix it?

I'm attempting to make a stacked bar chart mapping a variable to fill on a log10 scale.我正在尝试制作一个堆叠条形图来映射一个变量以在 log10 尺度上填充。 I'd like to pass it through ggplotly, in order to have data inspection possible via tooltip.我想通过 ggplotly 传递它,以便通过工具提示进行数据检查。

There are two problems.有两个问题。 First, when I log transform the scale of VAR.B in scale_fill_gradientn, the tooltips display transformed data, while the graph displays data in its original scale, which is unhelpful.首先,当我在 scale_fill_gradientn 中记录转换 VAR.B 的比例时,工具提示显示转换后的数据,而图形以其原始比例显示数据,这是无用的。

However, when I include the text aesthetic in ggplot to fix this issue, it breaks the order of the fill.但是,当我在 ggplot 中包含文本美学以解决此问题时,它会破坏填充顺序。 I haven't been able to find a way to fix both issues.我一直无法找到解决这两个问题的方法。

I have tried log10 transforming VAR.B in the dataframe itself.我已经尝试在数据帧本身中对 VAR.B 进行 log10 转换。 In this case, the tooltips match the displayed data, but I don't think this will be easily approachable for my audience.在这种情况下,工具提示与显示的数据相匹配,但我认为这对我的观众来说并不容易。 Also, leaving the dataset in a linear scale loses an important part of the story.此外,将数据集保留为线性比例会丢失故事的重要部分。

Dataset数据集

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"))

Dependencies依赖关系

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

This graph looks like it should, but the values displayed in hover text for VAR.B don't match the original scale此图看起来应该如此,但 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

This graph looks disordered, but the values displayed in hover text for VAR.B do match the original scale.此图看起来无序,但 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

If I leave the paste0() function out of the text aesthetic and only call VAR.B itself, then the tooltips display data in the original scale and the order of the fill is preserved.如果我将 paste0() 函数排除在文本美学之外而只调用 VAR.B 本身,那么工具提示会以原始比例显示数据,并保留填充顺序。 But the tooltip doesn't give a label for the data in this case.但是在这种情况下,工具提示没有为数据提供标签。

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

It seems to me that the paste0() function in the text aesthetic is bugged.在我看来,文本美学中的 paste0() 函数被窃听了。 If anyone can think of another way to fix all of these problems at once, I would greatly appreciate it.如果有人能想出另一种方法同时解决所有这些问题,我将不胜感激。

This happens, because text = paste0('VAR.B:', VAR.B))) creates a factor, that is ordered alphabetically.发生这种情况是因为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

Hope this helps :-) I edit the t, so it's more obvious which call produces what希望这会有所帮助:-) 我编辑了 t,所以更明显的是哪个调用产生了什么

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM