我不知道如何使用自定义点标记与geom_point
一起工作(尽管您可以按照@baptiste的建议创建自己的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
绘制图像作为点标记。 annotation_custom
似乎一次只能处理一个点,而不是一个点的矢量,所以我们将使用for循环来绘制每个点。我们有我们要绘制两个不同的图像,所以我们将使用为每一个单独的循环:
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)
}
最后,添加传说和关闭剪裁,使传说会出现在最终的情节:
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)
UPDATE:新ggimage
package可能ulimately使这更容易一点。下面是一个例子。我想对结果图进行改进。
更改图的纵横比也会改变图像的纵横比,而我更喜欢图像保持其原始纵横比。
宁静的形象有一个白色的背景,涵盖了剧情网格和玛尔的形象(因为宁静是在玛尔后绘制的)。在上面的例子中,我使白色背景变得透明。但是,即使当我将上面创建的栅格栅格保存为jpegs(以便我可以使用具有透明背景的Serenity版本)并重新加载它们(而不是像下面那样从URL中直接获取图像)时,Serenity仍然有一个白色的背景。
图例不使用图像作为“点标记”,而是具有标记通常会存在的空白区域。
也许未来版本的软件包将创建与这些问题相关的额外灵活性,或者可能已经有一种我不知道解决这些问题的方法。
df = data.frame(x=rep(1:4,2), y=c(1,1,2,4,6.5,5,5.5,4.8),
Firefly=rep(c("Serenity","Mal"),each=4),
image=rep(c("http://www.entertainmentearth.com/images/AUTOIMAGES/QMSER0179lg.jpg",
"http://cdn.pastemagazine.com/www/articles/2010/03/12/malcolm_reynolds.jpg"), each=4))
ggplot(df, aes(x, y)) +
geom_line(aes(group=Firefly)) +
geom_image(aes(image=image, size=Firefly)) +
theme_bw() +
scale_size_manual(values=c(0.1,0.15)) +
coord_fixed(ratio=2/3, xlim=c(0.5, 4.5), ylim=c(0,7))
你读[本SO后(http://stackoverflow.com/questions/20733328/labelling-the-plots-with-images-on-graph-in-ggplot2) ?这似乎是以前问过的问题。 –
我做了,但不完全是我想要的;那些是散点图。我正在寻找折线图,其中的点是形状,这将出现在图例中。我会编辑我的问题来澄清 – Ricky
最好的选择可能是[写你自己的geom](https://github.com/hadley/ggplot2/blob/master/vignettes/extending-ggplot2.Rmd#creating-a-新GEOM) – baptiste