49

是否有某种方法可以将特定的小图像用作带有 ggplot2 的散点图中的一个点。理想情况下,我希望根据变量调整图像大小。

这是一个例子:

library(ggplot2)
p <- ggplot(mtcars, aes(wt, mpg))
p + geom_point(aes(size = qsec, shape = factor(cyl)))

所以我基本上想知道是否有办法提供特定图像作为形状?

4

3 回答 3

30

这是一个极简的几何图形来显示光栅图像而不是点,

library(ggplot2)
library(grid)

## replace by a named list with matrices to be displayed
## by rasterGrob
.flaglist <- list("ar" = matrix(c("blue", "white", "blue"), 1), 
                  "fr" = matrix(c("blue", "white", "red"), 1))

flagGrob <- function(x, y, country, size=1, alpha=1){
  grob(x=x, y=y, country=country, size=size, cl = "flag")
}

drawDetails.flag <- function(x, recording=FALSE){

  for(ii in seq_along(x$country)){
    grid.raster(x$x[ii], x$y[ii], 
                width = x$size[ii]*unit(1,"mm"), height = x$size[ii]*unit(0.5,"mm"),
                image = .flaglist[[x$country[[ii]]]], interpolate=FALSE)
  }
}


scale_country <- function(..., guide = "legend") {
  sc <- discrete_scale("country", "identity", scales::identity_pal(), ..., guide = guide)

  sc$super <- ScaleDiscreteIdentity
  class(sc) <- class(ScaleDiscreteIdentity)
  sc
}

GeomFlag <- ggproto("GeomFlag", Geom,
                    required_aes = c("x", "y", "country"),
                    default_aes = aes(size = 5, country="fr"),

                    draw_key = function (data, params, size) 
                    {
                      flagGrob(0.5,0.5, country=data$country,  size=data$size)
                    },

                    draw_group = function(data, panel_scales, coord) {
                      coords <- coord$transform(data, panel_scales)     
                      flagGrob(coords$x, coords$y, coords$country, coords$size)
                    }
)

geom_flag <- function(mapping = NULL, data = NULL, stat = "identity",
                      position = "identity", na.rm = FALSE, show.legend = NA, 
                      inherit.aes = TRUE, ...) {
  layer(
    geom = GeomFlag, mapping = mapping,  data = data, stat = stat, 
    position = position, show.legend = show.legend, inherit.aes = inherit.aes,
    params = list(na.rm = na.rm, ...)
  )
}


set.seed(1234)
d <- data.frame(x=rnorm(10), y=rnorm(10), 
                country=sample(c("ar","fr"), 10, TRUE), 
                stringsAsFactors = FALSE)


ggplot(d, aes(x=x, y=y, country=country, size=x)) + 
  geom_flag() + 
  scale_country()

在此处输入图像描述

(ggflags 包的输出)

于 2016-03-23T07:45:58.360 回答
29

有一个图书馆ggimage可以做到这一点。在此处查看介绍小插曲

您只需在您data.frame的图片地址中添加一列,该地址可以存储在网络上或本地计算机上,然后您可以使用geom_image()

library("ggplot2")
library("ggimage")

# create a df

set.seed(2017-02-21)
d <- data.frame(x = rnorm(10),
                y = rnorm(10),
                image = sample(c("https://www.r-project.org/logo/Rlogo.png",
                                 "https://jeroenooms.github.io/images/frink.png"),
                               size=10, replace = TRUE)
                )
# plot2
  ggplot(d, aes(x, y)) + geom_image(aes(image=image), size=.05)

在此处输入图像描述

附言。请注意,这ggimage取决于EBImage。所以要安装gginamge我必须这样做:

# install EBImage
  source("https://bioconductor.org/biocLite.R")
  biocLite("EBImage")
# install ggimage
  install.packages("ggimage")
于 2017-04-13T11:36:38.630 回答
4

首先,这是你的答案:

为了向您展示如何更好地使用小部件来表示数据差异化,我向您推荐了 R 图形库中的chernoff 面示例:

替代文字
(来源:free.fr

生成此示例的所有代码都可以在该站点上找到。

或者,查看 ggplot 的stat_spoke以获得一个简单的小部件:( 来源:had.co.nz替代文字

grImport提供了一种将简单的 PDF 图像导入绘图以用作点的机制。

现在对您的示例进行批评。


这不是散点图。它本质上是一个有序数据点的流动列表,其中颜色用于指示文本变量之一,并且已使用无信息且冗余的小部件来构建数据,但在大小或形状方面不提供视觉反馈。

这不是一个好的图表,因为它完全无法回答所述问题“支付更多费用会带来更好的结果”,并且让读者自己努力得出这个结论(以及其他图表,如果有必要的话)。

此外,作者还浪费了 x、y 轴——这本来可以很好地用于通过输出和结果来定位元素,以提供对物有所值的直观理解。相反,他们选择按照人均成本与平均毕业率的比率来排序图标,这有点用处,但没有回答所述问题,并且无法直接直观地比较大学之间的相对比率,或者成本与价值的关系。

正如我所说,在我看来,这是一个糟糕的图表,如果你复制它,你的读者不会得到很好的服务。

于 2010-02-02T08:49:24.637 回答