Inspiration! A violin chart-like bulb

While designing Visible Data’s POUR-CAF iconograph I had the idea of making a violin chart in the shape of light bulb! Sounds like a fun project.
R
interactive dataviz
Author

Charlotte Jane Hadley

Published

June 22, 2026

I’m working on Visible Data’s iconography for the POUR-CAF principles and wanted to create something a different for the “understand” icon that avoided simply “brain” and also looked like a chart. Thankfully, I had a lightbulb moment. Lightbulb look like violin charts (or the other way round).

Visible Data has a premium subscription to Flaticons, which includes this lovely lightbulb icon.

Line style icon of a filament light bulb, including a bayonet fitting

I prompted Claude to generate a dataset that when visualised as a violin chart had a similar outline to that shape. It ended up trying to get exactly the outline before I had to interrupt and get something less perfect:

All from this code:

library("tidyverse")

set.seed(42)

# Generate data from a mixture of distributions that together suggest a
# light bulb silhouette, while retaining natural violin chart texture.
#
# Three components:
#   1. Large round bulb body — beta distribution centered ~0.65, wide spread
#   2. Neck pinch — small cluster of points near 0.18, very tight
#   3. Base cap — uniform-ish cluster near 0.06, narrow
n_bulb <- 3000
n_neck <- 180
n_base <- 300

# beta(2.5,4) skews the peak toward the lower end of the range,
# so when mapped to [0.22, 1.0] the widest point sits around 0.50-0.55
# and the upper half tapers like a dome rather than coming to a sharp diamond point
bulb <- rbeta(n_bulb, shape1 = 3, shape2 = 3) * 0.75 + 0.22
neck <- rnorm(n_neck, mean = 0.175, sd = 0.015)
base <- rnorm(n_base, mean = 0.07, sd = 0.020)

bulb_data <- tibble(
  x = "bulb",
  y = c(bulb, neck, base)
)

p <- ggplot(bulb_data, aes(x = x, y = y)) +
  geom_violin(
    fill = "#FFD700",
    color = "blue",
    linewidth = 1.2,
    bw = 0.04,
    trim = TRUE
  ) +
  coord_cartesian(xlim = c(0.55, 1.45)) +
  theme_void()

p

Was that fun? Was it inkeeping with my ethics?

This whole thing took about 30mins from conception to image I can add into Canva. That’s so much faster than if I’d have done this completely from scratch. I also really don’t know the parameters of the beta distribution well enough to have done this in less than 2h.

Did I enjoy it? Yes. That was fun. Was it inkeeping with my ethics? Eirgh.

  • I used a licensed image to get an outline. That’s kind of similar to when I trace images in Procreate in my spare time? Maybe.

  • I told Claude I wanted to use geom_violin and loaded the tidyverse for it. So I used my knowledge of how {ggplot2} worked instead of just “make this however”

  • I am fine-tuning the chart and embellishing it for the final icon.

Evenutally I settled on using this code:

library("tidyverse")
library("GPCDStools")

set.seed(42)

# Generate data from a mixture of distributions that together suggest a
# light bulb silhouette, while retaining natural violin chart texture.
#
# Three components:
#   1. Large round bulb body — beta distribution centered ~0.65, wide spread
#   2. Neck pinch — small cluster of points near 0.18, very tight
#   3. Base cap — uniform-ish cluster near 0.06, narrow
n_bulb <- 3000
n_neck <- 180
n_base <- 300

# beta(2.5,4) skews the peak toward the lower end of the range,
# so when mapped to [0.22, 1.0] the widest point sits around 0.50-0.55
# and the upper half tapers like a dome rather than coming to a sharp diamond point
bulb <- rbeta(n_bulb, shape1 = 3, shape2 = 3) * 0.75 + 0.22
neck <- rnorm(n_neck, mean = 0.175, sd = 0.015)
base <- rnorm(n_base, mean = 0.07, sd = 0.020)

bulb_data <- tibble(
  x = "bulb",
  y = c(bulb, neck, base)
)

bulb_glass <- ggplot(bulb_data, aes(x = x, y = y)) +
  geom_violin(
    fill = cols_gpcds$story_primary,
    color = cols_gpcds$ux_blue_mid,
    linewidth = 3,
    bw = 0.04,
    trim = TRUE
  ) +
  coord_cartesian(xlim = c(0.55, 1.45)) +
  theme_void()

ggsave(
  quarto_here("bulb_violin_glass.png"),
  bulb_glass,
  width = 6,
  height = 6,
  dpi = 150
)

bulb_transparent <- ggplot(bulb_data, aes(x = x, y = y)) +
  geom_violin(
    fill = "transparent",
    color = cols_gpcds$ux_blue_mid,
    linewidth = 3,
    bw = 0.04,
    trim = TRUE
  ) +
  coord_cartesian(xlim = c(0.55, 1.45)) +
  theme_void()

bulb_glow <- ggplot(bulb_data, aes(x = x, y = y)) +
  geom_violin(
    fill = cols_gpcds$story_primary,
    color = "transparent",
    linewidth = 3,
    bw = 0.04,
    trim = TRUE
  ) +
  coord_cartesian(xlim = c(0.55, 1.45)) +
  theme_void()

ggsave(
  quarto_here("bulb_violin_glow.png"),
  bulb_glow,
  width = 6,
  height = 6,
  dpi = 150
)

bulb_transparent <- ggplot(bulb_data, aes(x = x, y = y)) +
  geom_violin(
    fill = "transparent",
    color = cols_gpcds$ux_blue_mid,
    linewidth = 3,
    bw = 0.04,
    trim = TRUE
  ) +
  coord_cartesian(xlim = c(0.55, 1.45)) +
  theme_void()

ggsave(
  quarto_here("bulb_violin_transparent.png"),
  bulb_transparent,
  width = 6,
  height = 6,
  dpi = 150
)

bulb_bayonet <- ggplot(bulb_data, aes(x = x, y = y)) +
  geom_violin(
    fill = "#8f8f94",
    color = "#8f8f94",
    linewidth = 3,
    bw = 0.04,
    trim = TRUE
  ) +
  coord_cartesian(xlim = c(0.55, 1.45)) +
  theme_void()

ggsave(
  quarto_here("bulb_violin_bayonet.png"),
  bulb_bayonet,
  width = 6,
  height = 6,
  dpi = 150
)

All of this came together into this first-generation icon for the “understandable” principle:

Icon representing 'Understandable': the ability to interpret and make sense of data. A violin chart forms the shape of a lightbulb, combining a data visualisation with the symbol for insight.