使用自定义图像而不是R线图标记的标准形状

时间:2016-01-18 05:02:19

标签: r

R有许多标准符号/形状,可用作R折线图中数据点的标记(如果不明确,请参阅http://www.cookbook-r.com/Graphs/Shapes_and_line_types/我的意思)。

我想要做的是使用我自己的自定义图标(例如苹果,香蕉,樱桃等的GIF)代替标准形状。

我怎么能在R中这样做?不必是原生R图形,我对包ggplot2

开放

我的预期用途是在折线图中,标记也会出现在图例上。

这里的答案(Labelling the plots with images on graph in ggplot2)通过直接绘制图像来解决类似的问题,就好像它们是独立的项目一样,所以并不真正与数据/图例联系在一起。

1 个答案:

答案 0 :(得分:9)

我不知道如何使用与 let //list of original column names List1= {"Name1","Name2","Name3","Name4"}, //Create table Source = Table.FromRows({{1231,1233,4121,5232},{3546,3426,1246,3464}} , List1), RenameColumns = Table.TransformColumnNames(Source, MyFuncRenameColumns) in RenameColumns 一起使用的自定义点标记(尽管您可以按照@baptiste的建议创建自己的geom_point)。但是,如果您愿意承受一些编码痛苦,可以使用geom创建与annotation_custom相似的内容。痛苦的部分是你必须做一些手动调整(虽然你可能会创建程序逻辑,如果你要经常这样做,将为你处理一些)。情节也很缓慢。尽管如此,对它进行破解仍然很有趣。

加载包并获得两张将成为我们点标记的图像:

geom_point

创建虚假数据并设置情节:

library(ggplot2)
library(RCurl)
library(jpeg)
library(grid)

## Image 1
URL1 = "http://www.entertainmentearth.com/images/AUTOIMAGES/QMSER0179lg.jpg"
serenity = readJPEG(getURLContent(URL1))

## Image 2
URL2 = "http://cdn.pastemagazine.com/www/articles/2010/03/12/malcolm_reynolds.jpg"
mal = readJPEG(getURLContent(URL2))

# Crop the mal image
mal = mal[40:250,,]

## Turn images into raster grobs
serenity = rasterGrob(serenity)
mal = rasterGrob(mal)

# Make the white background transparent in the serenity image
serenity$raster[serenity$raster=="#FFFFFF"] = "#FFFFFF00" 

现在,使用# Create fake data df = data.frame(x=rep(1:4,2), y=c(1,1,2,4,6.5,5,5.5,4.8), g=rep(c("s","m"),each=4)) # Set up a plot p = ggplot(df, aes(x, y, group=g)) + geom_line() + theme_bw() 将图像绘制为点标记,而不是geom。 annotation_custom似乎一次只能使用一个点,而不是点矢量,因此我们将使用for循环绘制每个点。我们想要绘制两个不同的图像,因此我们将为每个图像使用单独的循环:

annotation_custom

最后,添加图例并关闭剪裁,以便图例显示在最终图中:

a=0.8
for (i in rownames(df[df$g=="s",])) {
  p = p + annotation_custom(serenity, df[i,"x"]-a,df[i,"x"]+a,df[i,"y"]-a,df[i,"y"]+a)  
}

b=0.4
for (i in rownames(df[df$g=="m",])) {
  p = p + annotation_custom(mal, df[i,"x"]-b,df[i,"x"]+b,df[i,"y"]-b,df[i,"y"]+b)  
}

enter image description here

更新:新的ggimage package可能会让这更容易。以下是一个例子。关于最终的情节我想改进一些事情。

  • 更改绘图的纵横比也会改变图像的纵横比,而我更喜欢图像保持原始纵横比。

  • Serenity图像的白色背景覆盖了绘图网格和Mal的图像(因为在Mal之后绘制了Serenity)。在上面的例子中,我使白色背景透明。但是,即使我将上面创建的栅格grobs保存为jpegs(以便我可以使用透明背景的Serenity版本)并重新加载它们(而不是像我下面那样直接从URL获取图像)Serenity的图像仍然有一个白色的背景。

  • 图例并未将图像用作"点标记"而是有一个空白区域,标记通常是。

也许该软件包的未来版本将创建与这些问题相关的额外灵活性,或者可能已经有一种我不知道的方式来解决这些问题。

a = 0.8*a
b = 0.8*b

p = p + coord_cartesian(xlim=c(0,5), ylim=c(0,7)) +
  theme(plot.margin=unit(c(1,10,1,1),"lines")) +
  annotation_custom(serenity, 5.8-a,5.8+a,3.4-a,3.4+a) +
  annotate(geom="text", x=5.8+0.5, y=3.4, label="Serenity", hjust=0) +
  annotation_custom(mal, 5.8-b,5.8+b,4.6-b,4.6+b) +
  annotate(geom="text", x=5.8+0.5, y=4.6, label="Mal", hjust=0)

# Turn off clipping
p <- ggplot_gtable(ggplot_build(p))
p$layout$clip <- "off"
grid.draw(p)

enter image description here