Ent*_*elR 3 plot r ggplot2 multiple-axes
I am going to use a dataset and plot that came from a previous problem (Here):
dat <- read.table(text = " Division Year OperatingIncome
1 A 2012 11460
2 B 2012 7431
3 C 2012 -8121
4 D 2012 15719
5 E 2012 364
6 A 2011 12211
7 B 2011 6290
8 C 2011 -2657
9 D 2011 14657
10 E 2011 1257
11 A 2010 12895
12 B 2010 5381
13 C 2010 -2408
14 D 2010 11849
15 E 2010 517",header = TRUE,sep = "",row.names = 1)
dat1 <- subset(dat,OperatingIncome >= 0)
dat2 <- subset(dat,OperatingIncome < 0)
ggplot() +
geom_bar(data = dat1, aes(x=Year, y=OperatingIncome, fill=Division),stat = "identity") +
geom_bar(data = dat2, aes(x=Year, y=OperatingIncome, fill=Division),stat = "identity") +
scale_fill_brewer(type = "seq", palette = 1)
Run Code Online (Sandbox Code Playgroud)
It includes the following plot, which is where my question comes in:

My question: Is it possible for me to change the y-axis label to two different labels on the same side? One would say "Negative Income" and be on the bottom portion of the y-axis. The other would say "Positive Income" and be on the upper portion of the SAME y-axis.
I have seen this question asked in terms of dual y-axis for different scales (on opposite sides), but I specifically want this on the same y-axis. Appreciate any help - I also would prefer to use ggplot2 for this problem, if possible.
您可以annotate用来添加负收入和正收入的标签。要在绘图面板外添加文本,您需要关闭剪辑。以下是在绘图面板内部和外部添加文本的示例:
# Plot
p = ggplot() +
geom_bar(data = dat1, aes(x=Year, y=OperatingIncome, fill=Division),stat = "identity") +
geom_bar(data = dat2, aes(x=Year, y=OperatingIncome, fill=Division),stat = "identity") +
scale_fill_brewer(type = "seq", palette = 1) +
geom_hline(yintercept=0, lwd=0.3, colour="grey20") +
scale_x_continuous(breaks=sort(unique(dat$Year))) +
theme_bw()
# Annotate inside plot area
p + coord_cartesian(xlim=range(dat$Year) + c(-0.45,0.4)) +
annotate(min(dat$Year) - 0.53 , y=c(-5000,5000), label=c("Negative Income","Positive Income"),
geom="text", angle=90, hjust=0.5, size=3, colour=c("red","blue"))
Run Code Online (Sandbox Code Playgroud)
# Annotate outside plot area by turning off clipping
pp = p + coord_cartesian(xlim=range(dat$Year) + c(-0.4,0.4)) +
annotate(min(dat$Year) - 0.9, y=c(-6000,10000), label=c("Negative Income","Positive Income"),
geom="text", angle=90, hjust=0.5, size=4, colour=c("red","blue")) +
labs(y="")
pp <- ggplot_gtable(ggplot_build(pp))
pp$layout$clip <- "off"
grid.draw(pp)
Run Code Online (Sandbox Code Playgroud)
您也可以cowplot按照@Gregor的建议使用。我之前没有尝试过,所以也许有比我在下面做的更好的方法,但是看起来您必须使用视口坐标而不是数据坐标来放置注释。
# Use cowplot
library(cowplot)
ggdraw() +
draw_plot(p + labs(y=""), 0,0,1,1) +
draw_label("Positive Income", x=0.01, y = 0.5, col="blue", size = 10, angle=90) +
draw_label("Negative Income", x=0.01, y = 0.15, col="red", size = 10, angle=90)
Run Code Online (Sandbox Code Playgroud)
我意识到问题中的数据仅用于说明,但是对于这样的数据,折线图可能更易于理解:
library(dplyr)
ggplot(dat, aes(x=Year, y=OperatingIncome, color=Division)) +
geom_hline(yintercept=0, lwd=0.3, colour="grey50") +
geom_line(position=position_dodge(0.2), alpha=0.5) +
geom_text(aes(label=Division), position=position_dodge(0.2), show.legend=FALSE) +
scale_x_continuous(breaks=sort(unique(dat$Year))) +
theme_bw() +
guides(colour=FALSE) +
geom_line(data=dat %>% group_by(Year) %>% summarise(Net=sum(OperatingIncome), Division=NA),
aes(x=Year, y=Net), alpha=0.4) +
geom_text(data=dat %>% group_by(Year) %>% summarise(Net=sum(OperatingIncome), Division=NA),
aes(x=Year, y=Net, label="Net"), colour="black")
Run Code Online (Sandbox Code Playgroud)
或者,如果需要条形图,则可能是这样的:
ggplot() +
geom_bar(data = dat %>% arrange(OperatingIncome) %>%
mutate(Division=factor(Division,levels=unique(Division))),
aes(x=Year, y=OperatingIncome, fill=Division),
stat="identity", position="dodge") +
geom_hline(yintercept=0, lwd=0.3, colour="grey20") +
theme_bw()
Run Code Online (Sandbox Code Playgroud)