R有许多标准符号/形状,可用作R折线图中数据点的标记(如果不明确,请参阅http://www.cookbook-r.com/Graphs/Shapes_and_line_types/我的意思) .
我想要做的是使用我自己的自定义图标(例如苹果,香蕉,樱桃等的GIF)代替标准形状.
我怎么能在R?不必是原生R图形,我对包裹ggplot2等开放
我的预期用途是在折线图中,标记也会出现在图例上.
这里的答案(通过ggplot2中的图形标记图形)通过直接绘制图像来解决类似的问题,就像它们是独立的项目一样,因此并不真正与数据/图例相关联.
我不知道使用自定义点标记的方法geom_point(尽管你可以geom根据@baptiste的建议创建自己的点标记).但是,如果您愿意承受一些编码痛苦,您可以使用它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"
Run Code Online (Sandbox Code Playgroud)
创建虚假数据并设置情节:
# 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()
Run Code Online (Sandbox Code Playgroud)
现在,使用annotation_custom将图像绘制为点标记,而不是geom .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)
}
Run Code Online (Sandbox Code Playgroud)
最后,添加图例并关闭剪裁,以便图例显示在最终图中:
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)
Run Code Online (Sandbox Code Playgroud)
更新:新ggimage包可能会使这更容易一点.以下是一个例子.关于最终的情节,我想改进一些事情.
更改绘图的纵横比也会改变图像的纵横比,而我更喜欢图像保持其原始纵横比.
Serenity图像有一个白色背景,覆盖了绘图网格和Mal的图像(因为Serenity是在Mal之后绘制的).在上面的例子中,我使白色背景透明.但是,即使我将上面创建的栅格grobs保存为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))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1386 次 |
| 最近记录: |