This package was first designed to set breakpoints for truncating the plot as I need to shrink outlier long branch of a phylogenetic tree.
Axis break or a so call gap plot is useful for large datasets that are not normally distributed and contain outliers. Sometimes we can transform the data (e.g. using log-transformation if the data was log-normal distributed) to solve this problem. But this is not always granted. The data may just simply contain outliers and these outliers are meaningful. A simple gap plot can solve this issue well to present the data in detail with both normal and extreme data.
This package provides several scale functions to break down a ‘gg’
plot into pieces and align them together with (gap plot) or without
(wrap plot or cut plot) ignoring subplots. Our methods are fully
compatible with ggplot2, so that users can still use the
+ operator to add geometric layers after creating a broken
axis.
If you use ggbreak in published research, please cite the following paper:
For creating gap plot, we only provide scale_x_break and
scale_y_break functions. Currently, it is not allowed to
apply both functions to set breakpoints for both x and y axes. However,
multiple breakpoints on a single axis are supported.
After breaking the plot, we can still superpose geometric layers and set themes.
library(ggplot2)
library(ggbreak)
library(patchwork)
set.seed(2019-01-19)
d <- data.frame(x = 1:20,
y = c(rnorm(5) + 4, rnorm(5) + 20, rnorm(5) + 5, rnorm(5) + 22)
)
p1 <- ggplot(d, aes(y, x)) + geom_col()
d2 <- data.frame(x = c(2, 18), y = c(7, 26), label = c("hello", "world"))
p2 <- p1 + scale_x_break(c(7, 17)) +
geom_text(aes(y, x, label=label), data=d2, hjust=1, colour = 'firebrick') +
xlab(NULL) + ylab(NULL) + theme_minimal()
p1 + p2
p2 + scale_x_break(c(18, 21))
p1 + scale_x_break(c(7, 17), scales = 1.5) + scale_x_break(c(18, 21), scales=2)
g <- ggplot(d, aes(x, y)) + geom_col()
g2 <- g + scale_y_break(c(7, 17), scales = 1.5) +
scale_y_break(c(18, 21), scale=2) + scale_y_reverse()
g + g2
Users can apply scale transform functions, such as
scale_x_log10 and scale_x_sqrt, to axis break
plot.
p2 <- p1 + scale_x_break(c(7, 17))
p3 <- p1 + scale_x_break(c(7, 17)) + scale_x_log10()
p2 + p3
coord_flipg + coord_flip() + scale_y_break(c(7, 18))
facet_grid and
facet_wrapset.seed(2019-01-19)
d <- data.frame(
x = 1:20,
y = c(rnorm(5) + 4, rnorm(5) + 20, rnorm(5) + 5, rnorm(5) + 22),
group = c(rep("A", 10), rep("B", 10)),
face=c(rep("C", 5), rep("D", 5), rep("E", 5), rep("F", 5))
)
p <- ggplot(d, aes(x=x, y=y)) +
geom_col(orientation="x") +
scale_y_reverse() +
facet_wrap(group~.,
scales="free_y",
strip.position="right",
nrow=2
) +
coord_flip()
pg <- p +
scale_y_break(c(7, 17), scales="free") +
scale_y_break(c(19, 21), scales="free")
print(pg)
pg <- pg + aes(fill=group) + theme(legend.position = "bottom")
print(pg)
pg + labs(title="test title", subtitle="test subtitle", tag="A tag", caption="A caption") +
theme_bw() +
theme(
legend.position = "bottom",
strip.placement = "outside",
axis.title.x=element_text(size=10),
plot.title = element_text(size = 22),
plot.subtitle = element_text(size = 16),
plot.tag = element_text(size = 10),
plot.title.position = "plot",
plot.tag.position = "topright",
plot.caption = element_text(face="bold.italic"),
)
require(ggplot2)
library(ggbreak)
set.seed(2019-01-19)
d <- data.frame(
x = 1:20,
y = c(rnorm(5) + 4, rnorm(5) + 20, rnorm(5) + 5, rnorm(5) + 22),
group = c(rep("A", 10), rep("B", 10))
)
p <- ggplot(d, aes(x=x, y=y)) +
scale_y_reverse() +
scale_x_reverse() +
geom_col(aes(fill=group)) +
scale_fill_manual(values=c("#00AED7", "#009E73")) +
facet_wrap(
group~.,
scales="free_y",
strip.position="right",
nrow=2
) +
coord_flip()
p +
scale_y_break(c(7, 10), scales=0.5, ticklabels=c(10, 11.5, 13)) +
scale_y_break(c(13, 17), scales=0.5, ticklabels=c(17, 18, 19)) +
scale_y_break(c(19,21), scales=1, ticklabels=c(21, 22, 23))
p <- ggplot(mpg, aes(displ, hwy)) +
geom_point() +
scale_y_continuous(
"mpg (US)",
sec.axis = sec_axis(~ . * 1.20, name = "mpg (UK)")
) +
theme(
axis.title.y.left = element_text(color="deepskyblue"),
axis.title.y.right = element_text(color = "orange")
)
p1 <- p + scale_y_break(breaks = c(20, 30))
p2 <- p + scale_x_break(breaks = c(3, 4))
p1 + p2
library(patchwork)
set.seed(2019-01-19)
d <- data.frame(
x = 1:20,
y = c(rnorm(5) + 4, rnorm(5) + 20, rnorm(5) + 5, rnorm(5) + 22)
)
p <- ggplot(d, aes(x, y)) + geom_col()
x <- p+scale_y_break(c(7, 17 ))
x + p
The scale_wrap() function wraps a ‘gg’ plot over
multiple rows to make plots with long x-axes easier to read.
p <- ggplot(economics, aes(x=date, y = unemploy, colour = uempmed)) +
geom_line()
p + scale_wrap(n=4)
Both categorical and numerical variables are supported.
ggplot(mpg, aes(class, hwy)) +
geom_boxplot() +
scale_wrap(n = 2)
The scale_x_cut or scale_y_cut cuts a ‘gg’
plot to several slices with the ability to specify which subplots to
zoom in or zoom out.
library(ggplot2)
library(ggbreak)
set.seed(2019-01-19)
d <- data.frame(
x = 1:20,
y = c(rnorm(5) + 4, rnorm(5) + 20, rnorm(5) + 5, rnorm(5) + 22)
)
p <- ggplot(d, aes(x, y)) + geom_col()
p + scale_y_cut(breaks=c(7, 18), which=c(1, 3), scales=c(3, 0.5))
The space parameter in scale_x_break(),
scale_y_break(), scale_x_cut() and
scale_y_cut() allows user to control the space between
subplots.
p + scale_y_cut(breaks=c(7, 18), which=c(1, 3), scales=c(3, 0.5), space=.5)
## original plot
p1 <- ggplot(mpg, aes(displ, hwy, color=factor(cyl))) + geom_point()
## ggbreak plot without legend
p2 <- p1 + scale_x_break(c(3, 4)) +
theme(legend.position="none")
## extract legend from original plot
leg = cowplot::get_legend(p1)
## redraw the figure
p3 <- ggplotify::as.ggplot(print(p2))
## place the legend
p3 + ggimage::geom_subview(x=.9, y=.8, subview=leg)
The features we introduced for scale_x_break and
scale_y_break also work for scale_wrap,
scale_x_cut and scale_y_cut.
You can use aplot::plot_list() to arrange
ggbreak objects with other ggplot objects. For
other functions, such as cowplot::plot_grid() and
gridExtra::grid.arrange(), you need to explictly call
print() to ggbreak object, see also https://github.com/YuLab-SMU/ggbreak/issues/36.
Using print() is a secret magic to make
ggbreak compatible with other packages, including export.