Using the function rasterize()
, users can rasterize any ggplot2 layer:
library(ggplot2)
library(ggrastr)
<- ggplot(diamonds, aes(carat, price, colour = cut))
plot
+ rasterise(geom_point(), dpi = 72) + theme(aspect.ratio = 1) plot
Note that with ggrastr changes in version 0.2.0, when the aspect ratio is distorted, the objects are rendered without distortion, i.e. the points in this example are still circles:
# Points remain round across different aspect ratios
+ rasterise(geom_point(), dpi = 72) + theme(aspect.ratio = 0.2) plot
By default, plots are rendered with Cairo. However, users now have the option to render plots with the ragg device. The motivation for using ragg
is that ragg
can be faster and has better anti-aliasing. That being said, the default ragg device also has some alpha blending quirks. Because of these quirks, users are recommended to use the ragg_png
option to work around the alpha blending.
The differences in devices are best seen at lower resolution:
# The default 'cairo' at dpi=5
+ rasterise(geom_point(), dpi = 5, dev = "cairo") plot
# Using 'ragg' gives better anti-aliasing but has unexpected alpha blending
+ rasterise(geom_point(), dpi = 5, dev = "ragg") plot
# Using 'ragg_png' solves the alpha blend, but requires writing a temporary file to disk
+ rasterise(geom_point(), dpi = 5, dev = "ragg_png") plot
Facets are rendered correctly without users having to adjust the width/height settings.
# Facets will not warp/distort points
set.seed(123)
+ rasterise(geom_point(), dpi = 300) + facet_wrap(~ sample(1:3, nrow(diamonds), 2)) plot
Users are also able to change the size of the raster objects with the parameter scale
. The default behavior is not to modify the size with scale=1
:
# unchanged scaling, scale=1
<- ggplot(diamonds, aes(carat, price, colour = cut))
plot + rasterise(geom_point(), dpi = 300, scale = 1) plot
Setting scale
to values greater than 1 will increase the size of the rasterized objects. In this case, scale=2
will double the size of the points in comparison to the original plot:
# larger objects, scale > 1
<- ggplot(diamonds, aes(carat, price, colour = cut))
plot + rasterise(geom_point(), dpi = 300, scale = 2) plot
Similarly, values less than 1 will result in smaller objects. Here we see scale=0.5
results in points half the size of the points in the original plot above:
# smaller objects, scale < 1
<- ggplot(diamonds, aes(carat, price, colour = cut))
plot + rasterise(geom_point(), dpi = 300, scale = 0.5) plot
As of ggrastr versions >=0.2.3
, users are also able to rasterize multiple layers at once using (valid) lists. In this example, we show how to rasterize the input list(geom_point(), geom_smooth())
:
# smaller objects, scale < 1
ggplot(mtcars, aes(wt, mpg)) + rasterise(list(geom_point(), geom_smooth()))
#> `geom_smooth()` using method = 'loess' and formula 'y ~ x'
Indeed, rasterize()
will even work with nested lists, e.g
<- sf::st_as_sf(maps::map('world', plot = FALSE, fill = TRUE))
world1 ggplot() + rasterise(
list(
list(
geom_sf(data = world1),
theme(panel.background = element_rect(fill = "skyblue"))
),list(
list(
geom_point(aes(x = rnorm(100, sd = 10), y = rnorm(100, sd = 10)))
),theme(panel.border = element_rect(fill = NA, colour = "blue"))
)
) )
The parameter dpi
is an integer which sets the desired resolution in dots per inch. With ggrastr versions >=0.2.2
, users can set this parameter globally, using options(). In the following example, plots will be rendered with dpi=750
after the user sets this with options(ggrastr.default.dpi=750)
:
## set ggrastr.default.dpi with options()
options(ggrastr.default.dpi=750)
<- ggplot(diamonds, aes(carat, price, colour = cut))
plot = plot + rasterise(geom_point()) + theme(aspect.ratio = 1)
new_plot print(new_plot)
## set back to default 300
options(ggrastr.default.dpi=300)
All other functions detailed below are wrapper functions provided for several geoms to guarantee compatibility with an older version of ggrastr
. However, we encourage users to use the rasterise()
function instead.
geom_point_rast
: raster scatter plotsgeom_jitter_rast
: raster jittered scatter plotsgeom_boxplot_jitter
: boxplots that allows to jitter and rasterize outlier pointsgeom_tile_rast
: raster heatmapgeom_beeswarm_rast
: raster bee swarm plotsgeom_quasirandom_rast
: raster quasirandom scatter plotSometimes you need to publish a figure in a vector format:
library(ggplot2)
library(ggrastr)
<- 10000
points_num <- data.frame(x=rnorm(points_num), y=rnorm(points_num), c=as.factor(1:points_num %% 2))
df <- ggplot(df, aes(x=x, y=y, color=c)) + scale_color_discrete(guide=FALSE)
gg
<- gg + geom_point(size=0.5)
gg_vec print(gg_vec)
#> Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
#> use `guide = "none"` instead.
But in other cases, your figure contains thousands of points, e.g. try points_num <- 500000
in the example above, and you will notice the performance issues—it takes significantly longer to render the plot:
gg_vec_plot_500000
In this case, a reasonable solution would be to rasterize the plot. But the problem is that all text becomes rasterized as well. Raster layers with ggrastr
were developed to prevent such a situation, here using geom_point_rast()
:
<- gg + geom_point_rast(size=0.5)
gg_rast print(gg_rast)
#> Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
#> use `guide = "none"` instead.
The plots look the same, but the difference in size can be seen when they are exported to pdfs. Unfortunately, there is a longer rendering time to produce such plots:
<- function(gg, name) {
PrintFileSize invisible(ggsave('tmp.pdf', gg, width=4, height=4))
cat(name, ': ', file.info('tmp.pdf')$size / 1024, ' Kb.\n', sep = '')
unlink('tmp.pdf')
}
PrintFileSize(gg_rast, 'Raster')
#> Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
#> use `guide = "none"` instead.
#> Raster: 312.4551 Kb.
PrintFileSize(gg_vec, 'Vector')
#> Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
#> use `guide = "none"` instead.
#> Vector: 556.8682 Kb.
As expected, the difference becomes larger with growth of number of points:
<- 1000000
points_num <- data.frame(x=rnorm(points_num), y=rnorm(points_num), c=as.factor(1:points_num %% 2))
df <- ggplot(df, aes(x=x, y=y, color=c)) + scale_color_discrete(guide=FALSE)
gg
<- gg + geom_point(size=0.5)
gg_vec <- gg + geom_point_rast(size=0.5)
gg_rast
PrintFileSize(gg_rast, 'Raster')
#> Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
#> use `guide = "none"` instead.
#> Raster: 400.4482 Kb.
PrintFileSize(gg_vec, 'Vector')
#> Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
#> use `guide = "none"` instead.
#> Vector: 54862.39 Kb.
Just like the example above withgeom_point_rast()
, users may also opt to create rasterized scatter plots with jitter. The geom geom_jitter_rast()
is similar to ggplot2::geom_jitter()
, but it creates a rasterized layer:
library(ggplot2)
library(ggrastr)
<- 5000
points_num <- data.frame(x=rnorm(points_num), y=rnorm(points_num), c=as.factor(1:points_num %% 2))
df <- ggplot(df, aes(x=x, y=y, color=c)) + scale_color_discrete(guide=FALSE)
gg
<- gg + geom_jitter_rast(raster.dpi=600)
gg_jitter_rast print(gg_jitter_rast)
#> Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
#> use `guide = "none"` instead.
Heatmaps also have similar issues with the default vectorized formats:
library(ggplot2)
library(ggrastr)
<- expand.grid(1:500, 1:500)
coords $Value <- 1 / apply(as.matrix(coords), 1, function(x) sum((x - c(50, 50))^2)^0.01)
coords<- ggplot(coords) + geom_tile(aes(x=Var1, y=Var2, fill=Value))
gg_tile_vec <- ggplot(coords) + geom_tile_rast(aes(x=Var1, y=Var2, fill=Value))
gg_tile_rast print(gg_tile_rast)
We can see that the rasterized plots using ggrastr
are lighter in size when rendered to pdf:
PrintFileSize(gg_tile_rast, 'Raster')
#> Raster: 46.77637 Kb.
PrintFileSize(gg_tile_vec, 'Vector')
#> Vector: 817.8398 Kb.
One can see a similar effect with violin plots:
library(ggplot2)
library(ggrastr)
<- ggplot(mtcars, aes(factor(cyl), mpg)) + geom_violin()
gg_violin_vec <- ggplot(mtcars) + geom_violin_rast(aes(factor(cyl), mpg))
gg_violin_rast print(gg_violin_rast)
## difference in size shown
PrintFileSize(gg_tile_rast, 'Raster')
#> Raster: 46.77637 Kb.
PrintFileSize(gg_tile_vec, 'Vector')
#> Vector: 817.8398 Kb.
Another type of plot with a potentially large number of small objects is geom_boxplot:
library(ggplot2)
library(ggrastr)
<- 5000
points_num <- data.frame(x=as.factor(1:points_num %% 2), y=log(abs(rcauchy(points_num))))
df <- ggplot(df, aes(x=x, y=y)) + scale_color_discrete(guide=FALSE)
gg
<- gg + geom_boxplot()
boxplot print(boxplot)
#> Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
#> use `guide = "none"` instead.
With a large number of objects, outlier points become noninformative. For example, here is the rendered plot with points_num <- 1000000
:
boxplot_1000000
For such a large number of points, it would be better to jitter them using geom_boxplot_jitter()
:
library(ggplot2)
library(ggrastr)
<- 500000
points_num <- data.frame(x=as.factor(1:points_num %% 2), y=log(abs(rcauchy(points_num))))
df <- ggplot(df, aes(x=x, y=y)) + scale_color_discrete(guide=FALSE)
gg
<- gg + geom_boxplot_jitter(outlier.size=0.1, outlier.jitter.width=0.3, outlier.alpha=0.5)
gg_box_vec print(gg_box_vec)
#> Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
#> use `guide = "none"` instead.
And this geom can be rasterized as well:
<- gg + geom_boxplot_jitter(outlier.size=0.1, outlier.jitter.width=0.3, outlier.alpha=0.5, raster.dpi=200)
gg_box_rast print(gg_box_rast)
#> Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
#> use `guide = "none"` instead.
PrintFileSize(gg_box_rast, 'Raster')
#> Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
#> use `guide = "none"` instead.
#> Raster: 119.8311 Kb.
PrintFileSize(gg_box_vec, 'Vector')
#> Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
#> use `guide = "none"` instead.
#> Vector: 225.9307 Kb.
ggrastr also allows users to create rasterized beeswarm plots. As described in the README for ggbeeswarm,
Beeswarm plots (aka column scatter plots or violin scatter plots) are a way of plotting points that would ordinarily overlap so that they fall next to each other instead. In addition to reducing overplotting, it helps visualize the density of the data at each point (similar to a violin plot), while still showing each data point individually.
The ggrastr geom geom_beeswarm_rast
is similar to ggbeeswarm::geom_beeswarm()
, but it provides a rasterized layer:
library(ggplot2)
library(ggrastr)
ggplot(mtcars) + geom_beeswarm_rast(aes(x = factor(cyl), y=mpg), raster.dpi=600, cex=1.5)
Analogously, geom_quasirandom_rast
is much like ggbeeswarm::geom_quasirandom()
, but with a rasterized layer:
library(ggplot2)
library(ggrastr)
ggplot(mtcars) + geom_quasirandom_rast(aes(x = factor(cyl), y=mpg), raster.dpi=600)
We encourage users to visit both https://CRAN.R-project.org/package=ggbeeswarm and the github repo at https://github.com/eclarke/ggbeeswarm for more details.