coolbutuseless / ggsvg

Use SVG images as ggplot points
https://coolbutuseless.github.io/package/ggsvg/
MIT License
138 stars 5 forks source link

`htmltools` tags composition #3

Open timelyportfolio opened 2 years ago

timelyportfolio commented 2 years ago

Wondering if using htmltools tags might be more understandable or readable for some R users. Happy to add an example to docs or README if helpful. The key is to add as.character(...tag...) to work with geom_point_svg.

all in one

library(htmltools)
library(ggplot2)
library(ggsvg)

arrow_svg <- tags$svg(
  viewBox = "0 0 100 100",
  tags$g(
    transform = "rotate(45 50 50)",
    tags$line(
      x1 = 10,
      y1 = 50,
      x2 = 90,
      y2 = 50,
      stroke = "black",
      'stroke-width' = 2
    ),
    tags$line(
      x1 = 70,
      y1 = 30,
      x2 = 90,
      y2 = 50,
      stroke = "black",
      'stroke-width' = 2
    ),
    tags$line(
      x1 = 70,
      y1 = 70,
      x2 = 90,
      y2 = 50,
      stroke = "black",
      'stroke-width' = 2
    )
  )
)
browsable(arrow_svg)
ggplot(data.frame(x=0,y=0)) +
  geom_point_svg(
    aes(x,y),
    svg = as.character(arrow_svg),
    size = 10
  )

composition

line1 <- tags$line(
  x1 = 10,
  y1 = 50,
  x2 = 90,
  y2 = 50,
  stroke = "black",
  'stroke-width' = 2
)
line2 <- tags$line(
  x1 = 70,
  y1 = 30,
  x2 = 90,
  y2 = 50,
  stroke = "black",
  'stroke-width' = 2
)
line3 <- tags$line(
  x1 = 70,
  y1 = 70,
  x2 = 90,
  y2 = 50,
  stroke = "black",
  'stroke-width' = 2
)

g <- tags$g(
  transform = "rotate(45 50 50)",
  line1,
  line2,
  line3
)

arrow_svg2 <- tags$svg(
  viewBox = "0 0 100 100",
  g
)

browsable(arrow_svg2)
ggplot(data.frame(x=0,y=0)) +
  geom_point_svg(
    aes(x,y),
    svg = as.character(arrow_svg2),
    size = 10
  )

perlin noise example

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Add rotate
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
g2 <- tags$g(
  transform = "rotate({{angle}} 50 50)",
  line1,
  line2,
  line3
)

arrow_svg3 <- tags$svg(
  viewBox = "0 0 100 100",
  g2
)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Create a plausible vector field
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
set.seed(13)
value <- 360 * as.vector(ambient::normalise(ambient::noise_perlin(c(10, 10))))
data  <- cbind(expand.grid(x=1:10, y=1:10), value)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Use 'value' to control the arrow angle
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ggplot(data) + 
  geom_raster(aes(x, y, fill = value)) + 
  geom_point_svg(
    aes(x, y, angle = I(value)), 
    svg = as.character(arrow_svg3),
    size = 10,
    defaults = list(angle = 0)
  ) + 
  theme_bw() +
  theme(legend.position = 'none') + 
  scale_fill_viridis_c()
baptiste commented 2 years ago

or maybe minisvg stag?