Fun pictures with ggplot2 and scico packages
R-bloggers 2026-04-18
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

This wonderful post from Jonathan Caroll give me idea to play with ggplot2 code and scico color palettes:
Also see this toot from Stefan Siegert, inspiring!
I took the code from the toot mentioned above, modified it, and used it to have a little fun creating graphics that look like paintings with imperfections around the edges, among other things.
All in all, I think it’s a good way to test color palettes.
When you get higher dot per inch images, it can be really cool.
# https://mastodon.social/@safest_integer/114296256313964335library(tidyverse)crossing(x=0:10, y=x) |> mutate(dx = rnorm(n(), 0, (y/20)^1.5), dy = rnorm(n(), 0, (y/20)^1.5)) |>ggplot() +geom_tile(aes(x=x+dx, y=y+dy, fill=y), colour='black', lwd=2, width=1, height=1, alpha=0.8, show.legend=FALSE) +scale_fill_gradient(high='#9f025e', low='#f9c929') +scale_y_reverse() + theme_void()
library(tidyverse)crossing(x=8:300, y=x[1:100]) |> mutate(dx = rnorm(n(), 0, (y/200)^1.5), dy = rnorm(n(), 0, (y/100)^1.5)) |> ggplot() + geom_tile(aes(x=x+dx, y=y+dy, fill=y), colour=NA, lwd=4, width=8, height=4, alpha=0.1, show.legend=FALSE) + scale_fill_gradient(high='#9f025e', low='#f9c929') + scale_y_reverse() + theme_void() + coord_fixed()

Here is the “Oleron” color palette from scico. What a beautiful palette for those who know this french island!
library(tidyverse)crossing(x=8:300, y=x[1:100]) |> mutate(dx = rnorm(n(), 0, (y/200)^1.5), dy = rnorm(n(), 0, (y/100)^1.5)) |> ggplot() + geom_tile(aes(x=x+dx, y=y+dy, fill=y), colour=NA, lwd=4, width=8, height=4, alpha=0.1, show.legend=FALSE) + scico::scale_fill_scico(palette = "oleron", direction = 1) + scale_y_reverse() + theme_void() + coord_fixed()

Now drawing waves, view at the top of the dune:
crossing(x=8:300, y=x[1:100]) |> mutate(dx = rnorm(n(), 0, (y/200)^1.5), dy = ifelse(y < 52, rnorm(n(), 0, (y/100)^1.5)+ ifelse(x %% 2 == 0, cos(x * 3 + y / 5)*4 + sin(x * 3 + y / 2)*2, 0) / 1.7, rnorm(n(), 0, (y/100)^1.5))) |> ggplot() + geom_tile(aes(x=x+dx, y=y+dy, fill=y), colour=NA, lwd=4, width=8, height=4, alpha=0.2, show.legend=FALSE) + scico::scale_fill_scico(palette = "oleron", #begin = 0.6, direction = 1) + scale_y_reverse() + theme_void() + coord_fixed()
The green might be vegetation from the dunes, or maybe seaweed.The blue might also be sky and wind, blue hour, there is definitely sand.

Back to bigger rectangles with a cyclic scico palette: romaO.
crossing(x=1:280, y=x) |> mutate(dx = rnorm(n(), 0, (x/40)^1.5), dy = rnorm(n(), 0, (y/40)^1.5)) |> ggplot() + geom_tile(aes(x=x+dx, y=y-dy*3, fill=y), colour='white', lwd=0.03, width=13, height=6, alpha=0.4, show.legend=FALSE) + scico::scale_fill_scico(palette = "romaO", #begin = 0.6, direction = 1) + scale_y_reverse() + theme_void() + theme(panel.background = element_rect(fill = "#2b2828")) + coord_fixed()

Now just play with a bit more magic: coord_polar
crossing(x=1:280, y=x) |> mutate(dx = rnorm(n(), 0, (x/40)^1.5), dy = rnorm(n(), 0, (y/40)^1.5)) |> ggplot() + geom_tile(aes(x=x+dx, y=y-dy*3, fill=y), colour='white', lwd=0.03, width=13, height=6, alpha=0.4, show.legend=FALSE) + scico::scale_fill_scico(palette = "romaO", #begin = 0.6, direction = 1) + scale_y_reverse() + theme_void() + theme(panel.background = element_rect(fill = "#2b2828")) + coord_polar()

Another one with vikO palette:
crossing(x=8:70, y=x[1:30]) |> mutate(dx = rnorm(n(), 0, (y/20)^1.5), dy = rnorm(n(), 0, (y/10)^1.5)+ ifelse(x %%2 == 0, cos(x * 3 + y / 5)*10, 0)) |> ggplot() + geom_tile(aes(x=x+dx, y=y+dy, fill=y), colour='grey70', lwd=0.1, width=8, height=4, alpha=0.6, show.legend=FALSE) + scico::scale_fill_scico(palette = "vikO", #begin = 0.6, direction = -1) + scale_y_reverse() + theme_void() + theme(panel.background = element_rect(fill = "#2b2828")) + coord_polar(theta = "x")

Finally back to Oleron palette with coord_polar:
crossing(x=8:70, y=x[1:30]) |> mutate(dx = rnorm(n(), 0, (y/20)^1.5), dy = rnorm(n(), 0, (y/10)^1.5)+ ifelse(x %%2 == 0, cos(x * 3 + y / 5)*10, 0)) |> ggplot() + geom_tile(aes(x=x+dx, y=y+dy, fill=y), colour=NA, lwd=1, width=8, height=4, alpha=0.4, show.legend=FALSE) + scico::scale_fill_scico(palette = "oleron", #begin = 0.6, direction = 1) + scale_y_reverse() + theme_void() + theme(panel.background = element_rect(fill = "grey5")) + ##2b2828 coord_polar(theta = "x")
Kind of like Earth, but not from the Moon. Just from R.

bukavu palette:
crossing(x=8:70, y=x[1:30]) |> mutate(dx = rnorm(n(), 0, (y/20)^1.5), dy = rnorm(n(), 0, (y/10)^1.5)+ ifelse(x %%2 == 0, cos(x * 3 + y / 5)*10, 0)) |> ggplot() + geom_tile(aes(x=x+dx, y=y+dy, fill=y), colour='grey5', lwd=0.2, width=8, height=4, alpha=0.4, show.legend=FALSE) + scico::scale_fill_scico(palette = "bukavu", #begin = 0.6, direction = 1) + scale_y_reverse() + theme_void() + theme(panel.background = element_rect(fill = "#2b2828")) + coord_polar(theta = "x")

Many thanks to:
- Thomas Lin Pedersen for this package: thomasp85/scico and Fabio Crameri for the palettes.
- Stefan Siegert
- Jonathan Caroll
- ggplot2 author and maintainers.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.