Tableau has chart type called “Packed Bubble Chart”, while I haven’t really utilized packed bubble chart much, I always thought they are fun and beautiful. I wanted to try creating same chart using R, and I came across package called packcircles.
Reading vignettes was really helpful to figure out how to use the package!!
- introduction vignettes - Progressive packing vignettes to get started on using this package.
Creating Bubble Packed Abstract Art…
I didn’t really have data sets handy to use it for this type of chart, so I’ve decided to play around with image. Initially I wanted to create images used to test colour blindness, but I wasn’t sure what colour palettes should be used to create these images.
Since I currently love Memoji on my iPhone, so I’ve decided I’d use Memoji image as base to create abstract art.
Steps
Step 1. Import image and convert image to data frame, so you can extract colour value (RGB)
Step 2. Genearate circle packing layout using circleProgressiveLayout function. The resulting data frame here contains center points of circle (x,y) and its radius.
Step 3. Convert x &amp; y coordinate from data frame in step 2 so that you can figure out what colour to fill the circle. i.e. Data Frame from Step 1 and Step 2 should be joined, so you need to adjust the scaling.
Step 4. Create data frame using circleLayoutVertices function for plotting with ggplot2. The resulting data frame now have specified amount of points per indivisual circle so that you can use geom_path or geom_polygon to draw.
Step 5. Join data from Step 4 with colour value from Step 3, so that you can use geom_polygon with fill value to colour the circle!
library(tidyverse) ## I need tidyverse for everything :) library(imager) ## to create data frame from image
library(scales) ## rescale function is so handy!
library(packcircles) ## making circle packing easy! ## Step 1
im % ## so that rgb value is in separate column.
rename(im_x=x,im_y=y) %__%
mutate(hex=rgb(c.1,c.2,c.3))
## Step 2 using circleProgressiveLayout function.
## Generate circle packing layout using rbeta distribution as size of circles
pack_layout % ## Step 3 - I want to figure out what colour to use, so I want layout &amp; image df to have same scaling. mutate(im_x=floor(rescale(x,to=range(im.df.colour$im_x))), im_y=floor(rescale(y,to=range(im.df.colour$im_y))),
## also generate id, so i can join the data frame easily later!
id=row_number()) %__% inner_join(im.df.colour %__% select(im_x,im_y,hex), by=c(&quot;im_x&quot;,&quot;im_y&quot;))
## Step 4 ## Using the layout above create data frame using circleLayoutVertices function so that you can plot circle using ggplot2
data_gg % inner_join(pack_layout %__% select(id,hex), by=c(&quot;id&quot;))
## Step 5
data_gg %__% ggplot(aes(x=x,y=y,group=id)) +
geom_polygon(aes(fill=hex)) + scale_fill_identity() + coord_equal() +
scale_y_reverse() + ## you need to reverse y-axis
theme_void() Just few more of these…
Good image to use is square image with above, but it’s fun turning into logo &amp; images!!!
Below are just few more things I’ve experimented with circle packing technique…
Experimenting with RGB Colour…
## Generate layout from 500 uniformly distributed number 0 to 1 as area.
pack_layout1 %
mutate(radius=0.7*radius), npoints=25) ## I want to draw smaller circle, so shrink the radius
data_gg2_2 % sample_n(700,weight=radius) %__%
mutate(radius=0.5*radius),npoints=25) data_gg2_3 % sample_n(900,weight=radius) %__%
mutate(radius=0.3*radius),npoints=25)
## Draw Black and White Version bw % ggplot(aes(x=x,y=y, group=id)) + geom_path(data=data_gg2, size=0.5, color=&quot;#00000090&quot;) +
geom_path(data=data_gg2_1,size=1, color=&quot;#00000090&quot;) +
geom_path(data=data_gg2_2,size=0.5, color=&quot;#00000090&quot;) +
geom_path(data=data_gg2_3,size=0.5, color=&quot;#00000090&quot;) +
scale_fill_identity() +
scale_color_identity() +
theme_void() +
coord_fixed()
## Draw colourful version hue % ggplot(aes(x=x,y=y, group=id)) + geom_polygon(aes(fill=hex)) + geom_path(data=data_gg2, size=0.5, color=&quot;#ffffff90&quot;) +
geom_path(data=data_gg2_1,size=1, color=&quot;#ffffff90&quot;) +
geom_path(data=data_gg2_2,size=0.5, color=&quot;#ffffff90&quot;) +
geom_path(data=data_gg2_3,size=0.5, color=&quot;#ffffff90&quot;) +
scale_fill_identity() +
scale_color_identity() +
theme_void() +
coord_fixed()
library(patchwork)
bw + hue