在ggplot2中删除geom_boxplot中的边框

时间:2022-06-15 13:06:22

This should seem relatively straightforward but I can't find an argument which would allow me to do this and I've searched Google and Stack for an answer.

这应该看起来比较简单,但是我找不到一个可以让我这么做的参数,我搜索了谷歌和Stack来寻找答案。

Sample code:

示例代码:

library(ggplot2)
library(plotly)

dat <- data.frame(cond = factor(rep(c("A","B"), each=200)), rating = c(rnorm(200),rnorm(200, mean=.8)))

p <- ggplot(dat, aes(x=cond, y=rating, fill=cond)) + geom_boxplot()

p <- ggplotly(p)

This outputs the first graph, I would want something like the second. 在ggplot2中删除geom_boxplot中的边框

它输出第一个图形,我想要第二个图形。

I tried including colour=cond but that gets rid of the median.

我试着包括颜色=cond,但是这去掉了中间值。

2 个解决方案

#1


2  

Two possible hacks for consideration, using the same dataset as Marco Sandri's answer.

使用与Marco Sandri的答案相同的数据集,可能需要考虑两种方法。

Hack 1. If you don't really need it to work in plotly, just static ggplot image:

修改1。如果你真的不需要它在情节上起作用,只需静态的ggplot图像:

ggplot(dat, aes(x=cond, y=rating, fill=cond)) + 
  geom_boxplot() +
  geom_boxplot(aes(color = cond),
               fatten = NULL, fill = NA, coef = 0, outlier.alpha = 0,
               show.legend = F)

在ggplot2中删除geom_boxplot中的边框

This overlays the original boxplot with a version that's essentially an outline of the outer box, hiding the median (fatten = NULL), fill colour (fill = NA), whiskers (coef = 0) & outliers (outlier.alpha = 0).

这覆盖了最初的箱线图,它的版本基本上是外框的轮廓,隐藏了中值(fatten = NULL),填充颜色(fill = NA), whiskers (coef = 0)和异常值(outlier)。α= 0)。

However, it doesn't appear to work well with plotly. I've tested it with the dev version of ggplot2 (as recommended by plotly) to no avail. See output below:

然而,它似乎并不能很好地与情节配合。我已经使用开发版本的ggplot2(按照plotly的建议)对它进行了测试,但没有效果。请参见下面的输出:

在ggplot2中删除geom_boxplot中的边框

Hack 2. If you need it to work in plotly:

黑客2。如果你需要它以一种缓慢的方式运作:

ggplot(dat %>%
         group_by(cond) %>%
         mutate(rating.IQR = case_when(rating <= quantile(rating, 0.3) ~ quantile(rating, 0.25),
                                       TRUE ~ quantile(rating, 0.75))), 
       aes(x=cond, y=rating, fill=cond)) + 
  geom_boxplot() +
  geom_boxplot(aes(color = cond, y = rating.IQR),
               fatten = NULL, fill = NA)

(ggplot output is same as above)

(ggplot输出与上面相同)

plotly doesn't seem to understand the coef = 0 & output.alpha = 0 commands, so this hack creates a modified version of the y variable, such that everything below P30 is set to P25, and everything above is set to P75. This creates a boxplot with no outliers, no whiskers, and the median sits together with the upper box limit at P75.

plotly似乎不理解coef = 0和输出。alpha = 0命令,因此这个技巧创建了y变量的一个修改版本,使P30以下的所有内容都设置为P25,上面的所有内容都设置为P75。这样就创建了一个没有异常值、没有胡须的箱线图,中间值与P75的上限值放在一起。

It's more cumbersome, but it works in plotly:

它更麻烦,但它运行缓慢:

在ggplot2中删除geom_boxplot中的边框

#2


1  

Here is an inelegant solution based on grobs:

这里有一个基于grobs的不雅解决方案:

set.seed(1)
dat <- data.frame(cond = factor(rep(c("A","B"), each=200)), 
                  rating = c(rnorm(200),rnorm(200, mean=.8)))

library(ggplot2)
library(plotly)
p <- ggplot(dat, aes(x=cond, y=rating, fill=cond)) + geom_boxplot() 

# Generate a ggplot2 plot grob
g <- ggplotGrob(p)

# The first box-and-whiskers grob
box_whisk1 <- g$grobs[[6]]$children[[3]]$children[[1]]
pos.box1 <- which(grepl("geom_crossbar",names(box_whisk1$children)))
g$grobs[[6]]$children[[3]]$children[[1]]$children[[pos.box1]]$children[[1]]$gp$col <-
  g$grobs[[6]]$children[[3]]$children[[1]]$children[[pos.box1]]$children[[1]]$gp$fill

# The second box-and-whiskers grob    
box_whisk2 <- g$grobs[[6]]$children[[3]]$children[[2]]
pos.box2 <- which(grepl("geom_crossbar",names(box_whisk2$children)))
g$grobs[[6]]$children[[3]]$children[[2]]$children[[pos.box2]]$children[[1]]$gp$col <-
  g$grobs[[6]]$children[[3]]$children[[2]]$children[[pos.box2]]$children[[1]]$gp$fill

library(grid)
grid.draw(g)

在ggplot2中删除geom_boxplot中的边框

P.S. To my knowledge, the above code cannot be used for generating plotly graphs.

附注:据我所知,以上代码不能用于生成阴谋图。

#1


2  

Two possible hacks for consideration, using the same dataset as Marco Sandri's answer.

使用与Marco Sandri的答案相同的数据集,可能需要考虑两种方法。

Hack 1. If you don't really need it to work in plotly, just static ggplot image:

修改1。如果你真的不需要它在情节上起作用,只需静态的ggplot图像:

ggplot(dat, aes(x=cond, y=rating, fill=cond)) + 
  geom_boxplot() +
  geom_boxplot(aes(color = cond),
               fatten = NULL, fill = NA, coef = 0, outlier.alpha = 0,
               show.legend = F)

在ggplot2中删除geom_boxplot中的边框

This overlays the original boxplot with a version that's essentially an outline of the outer box, hiding the median (fatten = NULL), fill colour (fill = NA), whiskers (coef = 0) & outliers (outlier.alpha = 0).

这覆盖了最初的箱线图,它的版本基本上是外框的轮廓,隐藏了中值(fatten = NULL),填充颜色(fill = NA), whiskers (coef = 0)和异常值(outlier)。α= 0)。

However, it doesn't appear to work well with plotly. I've tested it with the dev version of ggplot2 (as recommended by plotly) to no avail. See output below:

然而,它似乎并不能很好地与情节配合。我已经使用开发版本的ggplot2(按照plotly的建议)对它进行了测试,但没有效果。请参见下面的输出:

在ggplot2中删除geom_boxplot中的边框

Hack 2. If you need it to work in plotly:

黑客2。如果你需要它以一种缓慢的方式运作:

ggplot(dat %>%
         group_by(cond) %>%
         mutate(rating.IQR = case_when(rating <= quantile(rating, 0.3) ~ quantile(rating, 0.25),
                                       TRUE ~ quantile(rating, 0.75))), 
       aes(x=cond, y=rating, fill=cond)) + 
  geom_boxplot() +
  geom_boxplot(aes(color = cond, y = rating.IQR),
               fatten = NULL, fill = NA)

(ggplot output is same as above)

(ggplot输出与上面相同)

plotly doesn't seem to understand the coef = 0 & output.alpha = 0 commands, so this hack creates a modified version of the y variable, such that everything below P30 is set to P25, and everything above is set to P75. This creates a boxplot with no outliers, no whiskers, and the median sits together with the upper box limit at P75.

plotly似乎不理解coef = 0和输出。alpha = 0命令,因此这个技巧创建了y变量的一个修改版本,使P30以下的所有内容都设置为P25,上面的所有内容都设置为P75。这样就创建了一个没有异常值、没有胡须的箱线图,中间值与P75的上限值放在一起。

It's more cumbersome, but it works in plotly:

它更麻烦,但它运行缓慢:

在ggplot2中删除geom_boxplot中的边框

#2


1  

Here is an inelegant solution based on grobs:

这里有一个基于grobs的不雅解决方案:

set.seed(1)
dat <- data.frame(cond = factor(rep(c("A","B"), each=200)), 
                  rating = c(rnorm(200),rnorm(200, mean=.8)))

library(ggplot2)
library(plotly)
p <- ggplot(dat, aes(x=cond, y=rating, fill=cond)) + geom_boxplot() 

# Generate a ggplot2 plot grob
g <- ggplotGrob(p)

# The first box-and-whiskers grob
box_whisk1 <- g$grobs[[6]]$children[[3]]$children[[1]]
pos.box1 <- which(grepl("geom_crossbar",names(box_whisk1$children)))
g$grobs[[6]]$children[[3]]$children[[1]]$children[[pos.box1]]$children[[1]]$gp$col <-
  g$grobs[[6]]$children[[3]]$children[[1]]$children[[pos.box1]]$children[[1]]$gp$fill

# The second box-and-whiskers grob    
box_whisk2 <- g$grobs[[6]]$children[[3]]$children[[2]]
pos.box2 <- which(grepl("geom_crossbar",names(box_whisk2$children)))
g$grobs[[6]]$children[[3]]$children[[2]]$children[[pos.box2]]$children[[1]]$gp$col <-
  g$grobs[[6]]$children[[3]]$children[[2]]$children[[pos.box2]]$children[[1]]$gp$fill

library(grid)
grid.draw(g)

在ggplot2中删除geom_boxplot中的边框

P.S. To my knowledge, the above code cannot be used for generating plotly graphs.

附注:据我所知,以上代码不能用于生成阴谋图。