How to use an image as a legend key glyph?

做~自己de王妃 提交于 2020-05-17 05:26:11

问题


I am plotting a scatterplot in ggplot with icons and I am stuck with producing a legend using the icons.

THere is a function in the ggimage documentation called "draw_key_image" but I don't really understand how to use it or the required arguments.

The documentation says "data = A single row data frame containing the scaled aesthetics to display in this key" but this does not help me at all!

https://www.rdocumentation.org/packages/ggimage/versions/0.2.7/topics/draw_key

##Hopefully reproducible code with example data

##Icons downloaded from https://labs.mapbox.com/maki-icons/
library(ggplot2)
library(ggimage)
library(rsvg)

Activity<-"Walk"
x = -2
y = 2.5
icon<-".\\mapbox-maki-a6d16d4\\icons\\shoe-15.svg"
test_data<-data.frame( Activity, x, y, icon)

p_test<-ggplot(data = test_data,
          aes(x = x, 
              y = y))+
  geom_image(aes(image=icon), size=.03)
  p_test

Please could someone help me add a legend with the icon and label of "Walk"?

Many thanks, Jo


回答1:


This draw_key function is something that is supposed to work 'under the hood'. See documentation

Each geom has an associated function that draws the key when the geom needs to be displayed in a legend. These functions are called draw_key_*(), where * stands for the name of the respective key glyph. The key glyphs can be customized for individual geoms by providing a geom with the key_glyph argument (see layer() or examples below.)

I dare say, ggimage may possibly deserve some more development in this regard.

https://github.com/GuangchuangYu/ggimage/issues/18 shows that currently only three types of legend glyphs are supported, and you activate them with changing the options (see code below). One can also change the underlying draw_key function and instead of loading the R image, you can load your image. It needs to be a png though, so first you need to convert it to png.

You can find the source code which I modified here

The disadvantage is that it currently only accepts one image. In order to map several images to an aesthetic of your geom, you could find inspiration in grandmaster Baptiste's creation of a 'minimalist' geom. https://stackoverflow.com/a/36172385/7941188

library(ggplot2)
library(ggimage)

Activity<-c("Walk1", "Walk2")
x = 1:2
y = 2:3

icon<-"https://raw.githubusercontent.com/mapbox/maki/a6d16d49a967b73d9379890a7b26712b12b8daef/icons/shoe-15.svg"
bitmap <- rsvg::rsvg(icon, height = 50)

png::writePNG(bitmap, "shoe.png", dpi = 144)

test_data<-data.frame( Activity, x, y, icon)

options(ggimage.keytype = "image")

ggplot(data = test_data, aes(x = x, y = y)) +
  geom_image(aes(image=icon, color = Activity), size=.03)

The icon changed to the R logo:

Now let's modify the draw_key_image function. You also need to call it with the key_glyph argument in geom_image.


draw_key_image <- function (data, params, size) {
  kt <- getOption("ggimage.keytype")
if (kt == "image") {
    img <- magick::image_read("shoe.png")
    grobs <- lapply(seq_along(data$colour), function(i) {
      img <- ggimage:::color_image(img, data$colour[i], data$alpha[i])
      grid::rasterGrob(0.5, 0.5, image = img, width = 1, height = 1)
    })
    class(grobs) <- "gList"
    keyGrob <- ggplot2:::ggname("image_key", grid::gTree(children = grobs))
  }
  return(keyGrob)
}

ggplot(data = test_data, aes(x = x, y = y)) +
  geom_image(aes(image=icon, color = Activity), size=.03, 
             key_glyph = draw_key_image) # you need to add this argument

Created on 2020-04-20 by the reprex package (v0.3.0)

helpful threads: convert svg to png



来源:https://stackoverflow.com/questions/61327081/how-to-use-an-image-as-a-legend-key-glyph

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!