facet_wrap free_y 轴上的标题换行和小数位 (ggplot2)
facet_wrap Title wrapping & Decimal places on free_y axis (ggplot2)
我有一组代码可以使用 facet_wrap
:
生成多个图
ggplot(summ,aes(x=depth,y=expr,colour=bank,group=bank)) +
geom_errorbar(aes(ymin=expr-se,ymax=expr+se),lwd=0.4,width=0.3,position=pd) +
geom_line(aes(group=bank,linetype=bank),position=pd) +
geom_point(aes(group=bank,pch=bank),position=pd,size=2.5) +
scale_colour_manual(values=c("coral","cyan3", "blue")) +
facet_wrap(~gene,scales="free_y") +
theme_bw()
使用参考数据集,此代码生成如下图:
我想在这里实现两个目标:
- 保持 y 轴的自动缩放,但确保所有绘图只显示 1 位小数。我尝试创建一个新的四舍五入的
expr
值列,但它会导致错误栏无法正确排列。
- 我想把标题换行。我试过像 Change plot title sizes in a facet_wrap multiplot 那样更改字体大小,但有些基因名称太长,如果我将它们塞在一行中,最终会太小而无法阅读。有没有办法使用
facet_wrap
语句中的代码来换行文本?
这只解决了问题的第一部分。您可以创建一个函数来格式化轴并使用 scale_y_continous
进行调整。
df <- data.frame(x=rnorm(11), y1=seq(2, 3, 0.1) + 10, y2=rnorm(11))
library(ggplot2)
library(reshape2)
df <- melt(df, 'x')
# Before
ggplot(df, aes(x=x, y=value)) + geom_point() +
facet_wrap(~ variable, scale="free")
# label function
f <- function(x){
format(round(x, 1), nsmall=1)
}
# After
ggplot(df, aes(x=x, y=value)) + geom_point() +
facet_wrap(~ variable, scale="free") +
scale_y_continuous(labels=f)
可能不能作为明确的答案,但这里有一些关于您的问题的提示:
- 正在格式化 y-axis 刻度标签。
首先,让我们尝试使用 format
函数的直接解决方案。在这里,我们将所有 y-axis 刻度标签格式化为具有 1 个十进制值,在用 round
.
舍入后
formatter <- function(...){
function(x) format(round(x, 1), ...)
}
mtcars2 <- mtcars
sp <- ggplot(mtcars2, aes(x = mpg, y = qsec)) + geom_point() + facet_wrap(~cyl, scales = "free_y")
sp <- sp + scale_y_continuous(labels = formatter(nsmall = 1))
问题是,有时这种方法并不实用。例如,从你的图中取最左边的图。使用相同的格式,所有 y-axis 刻度标签将四舍五入为 -0.3
,这是不可取的。
另一种解决方案是将每个图的间隔修改为一组四舍五入的值。但是同样,以你的图最左边的图为例,它最终只有一个标签点,-0.3
另一种解决方案是将标签格式化为科学形式。为简单起见,您可以修改 formatter
函数如下:
formatter <- function(...){
function(x) format(x, ..., scientific = T, digit = 2)
}
现在您可以为所有地块使用统一格式y-axis。不过,我的建议是在四舍五入后将标签设置为小数点后两位。
- 包装分面标题
这可以使用 facet_wrap
中的 labeller
参数来完成。
# Modify cyl into factors
mtcars2$cyl <- c("Four Cylinder", "Six Cylinder", "Eight Cylinder")[match(mtcars2$cyl, c(4,6,8))]
# Redraw the graph
sp <- ggplot(mtcars2, aes(x = mpg, y = qsec)) + geom_point() +
facet_wrap(~cyl, scales = "free_y", labeller = labeller(cyl = label_wrap_gen(width = 10)))
sp <- sp + scale_y_continuous(labels = formatter(nsmall = 2))
必须注意,wrap函数检测space将标签分隔成行。因此,在您的情况下,您可能需要修改变量。
scale_*_continuous(..., labels = function(x) sprintf("%0.0f", x))
在我的案例中有效。
我有一组代码可以使用 facet_wrap
:
ggplot(summ,aes(x=depth,y=expr,colour=bank,group=bank)) +
geom_errorbar(aes(ymin=expr-se,ymax=expr+se),lwd=0.4,width=0.3,position=pd) +
geom_line(aes(group=bank,linetype=bank),position=pd) +
geom_point(aes(group=bank,pch=bank),position=pd,size=2.5) +
scale_colour_manual(values=c("coral","cyan3", "blue")) +
facet_wrap(~gene,scales="free_y") +
theme_bw()
使用参考数据集,此代码生成如下图:
我想在这里实现两个目标:
- 保持 y 轴的自动缩放,但确保所有绘图只显示 1 位小数。我尝试创建一个新的四舍五入的
expr
值列,但它会导致错误栏无法正确排列。 - 我想把标题换行。我试过像 Change plot title sizes in a facet_wrap multiplot 那样更改字体大小,但有些基因名称太长,如果我将它们塞在一行中,最终会太小而无法阅读。有没有办法使用
facet_wrap
语句中的代码来换行文本?
这只解决了问题的第一部分。您可以创建一个函数来格式化轴并使用 scale_y_continous
进行调整。
df <- data.frame(x=rnorm(11), y1=seq(2, 3, 0.1) + 10, y2=rnorm(11))
library(ggplot2)
library(reshape2)
df <- melt(df, 'x')
# Before
ggplot(df, aes(x=x, y=value)) + geom_point() +
facet_wrap(~ variable, scale="free")
# label function
f <- function(x){
format(round(x, 1), nsmall=1)
}
# After
ggplot(df, aes(x=x, y=value)) + geom_point() +
facet_wrap(~ variable, scale="free") +
scale_y_continuous(labels=f)
可能不能作为明确的答案,但这里有一些关于您的问题的提示:
- 正在格式化 y-axis 刻度标签。
首先,让我们尝试使用 format
函数的直接解决方案。在这里,我们将所有 y-axis 刻度标签格式化为具有 1 个十进制值,在用 round
.
formatter <- function(...){
function(x) format(round(x, 1), ...)
}
mtcars2 <- mtcars
sp <- ggplot(mtcars2, aes(x = mpg, y = qsec)) + geom_point() + facet_wrap(~cyl, scales = "free_y")
sp <- sp + scale_y_continuous(labels = formatter(nsmall = 1))
问题是,有时这种方法并不实用。例如,从你的图中取最左边的图。使用相同的格式,所有 y-axis 刻度标签将四舍五入为 -0.3
,这是不可取的。
另一种解决方案是将每个图的间隔修改为一组四舍五入的值。但是同样,以你的图最左边的图为例,它最终只有一个标签点,-0.3
另一种解决方案是将标签格式化为科学形式。为简单起见,您可以修改 formatter
函数如下:
formatter <- function(...){
function(x) format(x, ..., scientific = T, digit = 2)
}
现在您可以为所有地块使用统一格式y-axis。不过,我的建议是在四舍五入后将标签设置为小数点后两位。
- 包装分面标题
这可以使用 facet_wrap
中的 labeller
参数来完成。
# Modify cyl into factors
mtcars2$cyl <- c("Four Cylinder", "Six Cylinder", "Eight Cylinder")[match(mtcars2$cyl, c(4,6,8))]
# Redraw the graph
sp <- ggplot(mtcars2, aes(x = mpg, y = qsec)) + geom_point() +
facet_wrap(~cyl, scales = "free_y", labeller = labeller(cyl = label_wrap_gen(width = 10)))
sp <- sp + scale_y_continuous(labels = formatter(nsmall = 2))
必须注意,wrap函数检测space将标签分隔成行。因此,在您的情况下,您可能需要修改变量。
scale_*_continuous(..., labels = function(x) sprintf("%0.0f", x))
在我的案例中有效。