将facet_wrap与ggplotly一起使用的第一个和最后一个切面大于中间切面

问题描述 投票:3回答:1

使用示例数据:

library(tidyverse)
library(plotly)

myplot <- diamonds %>% ggplot(aes(clarity, price)) +
  geom_boxplot() +
  facet_wrap(~ clarity, ncol = 8, scales = "free", strip.position = "bottom") +
  theme(axis.ticks.x = element_blank(),
        axis.text.x = element_blank(),
        axis.title.x = element_blank())

ggplotly(myplot)

返回类似:

enter image description here

与第一个和最后一个相比,内部小平面的缩放比例惊人,并且有很多额外的填充。我试图从这些问题中找到解决方案:

ggplotly not working properly when number are facets are more

R: facet_wrap does not render correctly with ggplotly in Shiny app

[通过反复试验,我在panel.spacing.x = unit(-0.5, "line")中使用了theme(),它看起来更好一些,虽然没有很多多余的填充,但是内部的面仍然明显较小。

enter image description here

也是一个额外的问题,但并不重要,当我将标签设置在底部时,条形标签在ggplotly()调用中位于顶部。似乎是一个持续存在的问题here,有人可以使用变通方法吗?

编辑:在我的真实数据集中,我需要每个构面的y轴标签,因为它们的比例非常不同,所以我将它们保留在示例中,这就是为什么我需要facet_wrap。我的真实数据集的屏幕截图,用于解释:

enter image description here

r ggplot2 plotly ggplotly
1个回答
0
投票

[具有许多非常不同的值的变量,看来无论如何,您最终都将面临具有挑战性的格式,这意味着其中之一

  1. 刻面的宽度会有所不同,或
  2. 标签将不可读,或
  3. 该图太宽了,无法显示而没有滚动条。

因此,我建议针对每个唯一的清晰度重新缩放price列,并设置scale='free_x。我仍然希望有人能提出更好的答案。但是,这就是我要做的:

Plot 1:重定比例的值和scale='free_x

enter image description here

代码1:

#install.packages("scales")
library(tidyverse)
library(plotly)
library(scales)

library(data.table)
setDT(df)

df <- data.frame(diamonds)

df['price'][df$clarity == 'VS1', ] <- filter(df['price'], df['clarity']=='VS1')*2

# rescale price for each clarity
setDT(df)
clarities <- unique(df$clarity)
for (c in clarities){
  df[clarity == c, price := rescale(price)]
}

df$price <- rescale(df$price)

myplot <- df %>% ggplot(aes(clarity, price)) +
  geom_boxplot() +
  facet_wrap(~ clarity, scales = 'free_x', shrink = FALSE, ncol = 8, strip.position = "bottom") +
  theme(axis.ticks.x = element_blank(),
        axis.text.x = element_blank(),
        axis.title.x = element_blank())

p <- ggplotly(myplot)
p

当然,由于值已经重新调整,因此这只会深入了解每个类别的内部分布。如果要显示原始价格数据并保持可读性,建议通过将width设置得足够大为滚动条腾出空间。

图2: scales='free',宽度足够大:

enter image description here

代码2:

library(tidyverse)
library(plotly)

df <- data.frame(diamonds)

df['price'][df$clarity == 'VS1', ] <- filter(df['price'], df['clarity']=='VS1')*2

myplot <- df %>% ggplot(aes(clarity, price)) +
  geom_boxplot() +
  facet_wrap(~ clarity, scales = 'free', shrink = FALSE, ncol = 8, strip.position = "bottom") +
  theme(axis.ticks.x = element_blank(),
        axis.text.x = element_blank(),
        axis.title.x = element_blank())

p <- ggplotly(myplot, width = 1400)
p

并且,当然,如果您的值在各个类别之间变化不大,scales='free_x'会很好地工作。

图3: scales='free_x

enter image description here

代码3:

library(tidyverse)
library(plotly)

df <- data.frame(diamonds)

df['price'][df$clarity == 'VS1', ] <- filter(df['price'], df['clarity']=='VS1')*2

myplot <- df %>% ggplot(aes(clarity, price)) +
  geom_boxplot() +
  facet_wrap(~ clarity, scales = 'free_x', shrink = FALSE, ncol = 8, strip.position = "bottom") +
  theme(axis.ticks.x = element_blank(),
        axis.text.x = element_blank(),
        axis.title.x = element_blank())

p <- ggplotly(myplot)
p
© www.soinside.com 2019 - 2024. All rights reserved.