使用示例数据:
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)
返回类似:
与第一个和最后一个相比,内部小平面的缩放比例惊人,并且有很多额外的填充。我试图从这些问题中找到解决方案:
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()
,它看起来更好一些,虽然没有很多多余的填充,但是内部的面仍然明显较小。
也是一个额外的问题,但并不重要,当我将标签设置在底部时,条形标签在ggplotly()
调用中位于顶部。似乎是一个持续存在的问题here,有人可以使用变通方法吗?
编辑:在我的真实数据集中,我需要每个构面的y轴标签,因为它们的比例非常不同,所以我将它们保留在示例中,这就是为什么我需要facet_wrap
。我的真实数据集的屏幕截图,用于解释:
[具有许多非常不同的值的变量,看来无论如何,您最终都将面临具有挑战性的格式,这意味着其中之一
因此,我建议针对每个唯一的清晰度重新缩放price
列,并设置scale='free_x
。我仍然希望有人能提出更好的答案。但是,这就是我要做的:
Plot 1:重定比例的值和scale='free_x
代码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'
,宽度足够大:
代码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
代码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