帮助你happy地用ggplot2和magick画各种带渐变效果的图表(特别是渐变条形图)或其他沙雕图表的R包plothelper。现在magick已经成了R里边的主流图片处理包了,我希望大家不仅用它和ggplot2来画图表,而且还可以尝试用它们来做PPT或海报之类的。
本文只是展示一下这个包的功能,具体的参数设置和使用方法还请看详细的英文手册:http://mirrors.ustc.edu.cn/CRAN/web/packages/plothelper/plothelper.pdf
-image_crop_click,用鼠标点击来确定截取图片的哪一部分。这个比image_crop方便多了。我一直希望magick包能自己加一个,不过它没有,所以只好我自己写了。既可截取一个矩形区域,也可以截取一个不规则区域
-image_modify_local和image_modify_local2,用鼠标截取图片的一部分(可以是矩形也可以是不规则图形),对它进行改变而保持图片其他部分不变(或者相反,对图片其他部分进行修改但不改变这一部分)。这两个函数目的相同但参数设置方法不同
还有一个我自己感觉很好玩儿的函数是image_col_numeric,它的原理很简单,就是根据原来图片的灰度值对它进行重新着色。也就是说,图片原来是五颜六色的,而这个函数会先把它转成黑白图片,再根据灰度染上——比如说,从蓝色到红色——的渐变色
2019-06-24更新0.1.3版,新加annotation_transparent_text函数用来加透明文字,annotation_shading_polygon用来画不规则渐变多边形,这就弥补了annotation_raster只能画渐变矩形的不足。具体用法见下边的例子。
安装:
install.packages("plothelper")
library(plothelper)
library(magick)
library(tibble)
plothelper里的函数分成四类,第一类用于画图,第二类用于生成图形的坐标,第三类用于线性变换,第四类用于处理图片(也就是那些image_*的函数)。
geom_shading_bar是一个像geom_point一样的图层,可以代替gg_shading_bar。两者都是用来画渐变条形图的,但前者既然是图层,那显然更加灵活,推荐使用。而gg_shading_bar生成的图也可以和ggplot的其他图层叠加。但注意不要再往上加ggplot()了,也不要使用coord_fixed()。另外,gg_shading_bar跟geom_bar的区别在于前者只接受计算好的数值向量。
先放一个效果图吧。
每个条形都可以有自己的渐变色。
v=c(2, 3, 4, 8, 10, 15)
r=list(
c("lightseagreen", "orangered2"),
c("grey", "khaki2"),
c("slateblue4", "red"),
c("olivedrab2", "orange1"),
c("darkorchid2", "yellow"),
c("forestgreen", "brown2")
)
# 写法一
p=gg_shading_bar(v, raster=r, smooth=40, flip=TRUE)
# 写法二
tib=tibble(x=paste("x", 1: 6, sep=""), v, r)
p=ggplot(tib)+coord_flip()+
geom_shading_bar(aes(x=x, y=v, raster=r), flip=TRUE)
# 不管用以上哪种写法,都可以往上加东西
p=p+geom_text(aes(x=1: length(v), y=v+1, label=v), size=6)
p+scale_x_discrete(name="")+scale_y_continuous(name="number")+
theme(
panel.grid=element_blank(),
panel.background=element_blank(),
plot.background=element_rect(fill="#F2F1ED"),
axis.title=element_text(size=16, color="black"),
axis.text=element_text(size=16, color="black"),
axis.ticks.y=element_blank(),
axis.line.x=element_line(color="black")
)
注意渐变方式有两种:
第一种是所有条形都使用一个渐变范围。
x=paste("x", 1: 6, sep="")
v=c(-2, -3, 4, 8, 10, 15)
ggplot()+coord_flip()+
geom_shading_bar(aes(x,v,raster=list(c("blue","red"))), width=0.8, flip=TRUE)
第二种是每个条形根据它所代表的数值的大小使用部分颜色。请注意,下图与上图使用的都是从蓝色到红色的渐变,但条形的渐变方式是不同的。
ggplot()+coord_flip()+
geom_shading_bar(aes(x,v,raster=list(c("blue","red"))), width=0.8, flip=TRUE, equal_scale=TRUE)
r1=image_read("###图片kula.png") # 从https://github.com/githubwwwjjj/plothelper/blob/master/kula.png下载图片
r2=matrix(c("red", "green", "blue", "purple"), nrow=2)
r3=matrix(rainbow(7))
r=list(r1, r2, r3)
tib=tibble::tibble(xmin=c(1, 3, 5), xmax=c(2, 4, 8), ymin=c(0, 2, 3), ymax=c(3, 4, 6), r)
ggplot(tib)+
geom_multi_raster(aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, raster=r))
下图中,用geom_polygon画的蓝色矩形本来是正方形,但由于aspect ratio的问题看起来却是长方形,而且其形状会随窗口改变而改变;然而,用geom_rect_cm画的矩形的形状则不会发生变化。
ggplot()+xlim(-0.5, 10.5)+ylim(0, 3)+
geom_rect_cm(aes(x=1: 10, y=rep(2, 10)), fill="red", width=rep(1, 10), height=rep(1: 2, each=5))+
geom_polygon(aes(x=c(0, 1, 1, 0), y=c(0, 0, 1, 1)), fill="blue")
dat=data.frame(x=1: 10, y=rep(5, 10), R=rep(c(0.5, 1), 5))
ggplot(dat)+coord_fixed()+xlim(0, 11)+ylim(1, 9)+
geom_circle_cm(aes(x=x, y=y, rcm=R))
即使使用极坐标,形状也不会改变。
dat=data.frame(x=1: 10, y=rep(5, 10), R=rep(c(0.5, 1), 5))
ggplot() + coord_polar()+xlim(0, 11)+ylim(1, 9)+theme_void()+theme(plot.background=element_rect(fill="black"))+
geom_circle_cm(data=dat, show.legend=FALSE, aes(x=x, y=y, rcm=R, alpha=x), fill="red")+
geom_line(aes(x=c(0, 11), y=c(8, 8)), color="grey")
geom_ellipse_cm用来画形状不随坐标系和aspect ratio改变的椭圆形。要注意的是:需要用参数rcm来调整大小,用ab来调整圆被压扁的程度,但这两个数都无法严格指定椭圆的长半径和短半径(也就是说,无法像a=2, b=1这样指定半径)。
dat=data.frame(x=1: 10, y=rep(5, 10), R=rep(c(0.5, 1), 5))
ggplot(dat) + coord_fixed()+xlim(0, 11)+ylim(1, 9)+
geom_ellipse_cm(aes(x=x, y=y, rcm=R), ab=2)
mytext=c("佩服三连", "厉害厉害", "可以可以", "666")
color1=c("khaki", "orange", "orangered", "orangered1")
color2=rep("black", 4)
g=textgif(mytext, text_color=color1, bg_color=color2, fps=2, width=259, height=129)
# width和height根据需要随便调
# mgaick::image_write(g, "f:/GGG.gif", format="gif") # 假设要以"f:/GGG.gif"为文件名保存
annotation_transparent_text,透明文字,主要作用就是画那种底下的颜色能够透过来的文字,当然,放置字的那个label也可以是图片之类的东西,具体请看这个函数的文档中关于参数bg的说明。
m=colorRampPalette(rainbow(7))(20)
m=matrix(m, nrow=1)
ggplot()+coord_fixed()+
xlim(0, 7)+ylim(-2, 4)+theme_void()+
annotation_raster(
raster=m,
xmin=0, ymin=-3,
xmax=7, ymax=5,
interpolate=TRUE
)+
annotation_transparent_text(
label="R\nDATA\nVISUALIZATION",
xmin=0, xmax=7,
ymin=-1, ymax=3,
family="sans", fontface=2, alpha=0.6,
place="left", expand=c(0.08, 0.02)
)
poly=ellipsexy(-1, 0, a=1, b=1)
m=matrix(rainbow(10), nrow=1)
ggplot()+
coord_fixed(expand=FALSE)+
scale_y_continuous(limits=c(-1.5, 1.5))+
scale_x_continuous(limits=c(-3, 6), breaks=-3: 6, labels=-3: 6)+
annotation_shading_polygon(poly, raster=m)+
annotation_shading_polygon(poly, xmin=1, xmax=5, ymin=-1, ymax=1, raster=m)
img=image_read("###图片kula.png") # 从https://github.com/githubwwwjjj/plothelper/blob/master/kula.png下载图片
img=image_resize(img, "100x300!")
blues=matrix(c("purple", "deepskyblue1", "midnightblue", "midnightblue", "black", "yellow"))
ggplot()+xlim(-1, 1)+ylim(0, 2.5)+coord_fixed()+
annotation_raster(img, xmin=-1, xmax=0, ymin=0, ymax=2.5)+
annotation_shading_polygon(shape=img, xmin=0, xmax=1, ymin=0, ymax=2.5, raster=blues)
# 第一步:读图片
img=magick::image_read("https://raw.githubusercontent.com/githubwwwjjj/plothelper/master/spiderman.PNG")
# 第二步:画条形图
p=ggplot()+geom_bar(aes(x=1: 5, y=1: 5), stat="identity")+coord_flip()
# 第三步:合在一起
p=ggplot()+annotation_shading_polygon(shape=p, raster=img)
p+theme_void()+theme(plot.background=element_rect(fill="grey10"))
dat1=ellipsexy(
x=1, y=1, a=seq(1, 4, length.out=8), angle=seq(0, pi, length.out=8),
xytype="middleleft", n=30, todf=TRUE
)
ggplot()+
coord_fixed()+
geom_polygon(show.legend=FALSE, data=dat1, aes(x=x, y=y, group=g, fill=factor(g)), alpha=0.3)
dat1=rectxy(x=1: 5, y=1: 5, a=2, b=1, angle=seq(0, pi, length.out=5), xytype="middle", todf=TRUE)
ggplot()+coord_fixed()+
geom_polygon(show.legend=FALSE, data=dat1, aes(x, y, group=g, fill=factor(g)), alpha=0.5)
举个例子,以下函数x_square给出了画抛物线y=A*(x^2)+B的方式,然后把它套进ANYxy,就可以批量生成曲线了。
x_square=function(start, end, A, B){
x=seq(start, end, 0.1)
data.frame(x=x, y=A*(x^2)+B)
}
dat=ANYxy(myfun=x_square,
start=-1, end=1, A=c(1, 2, 3, 4), MoreArgs=list(B=1),
group=TRUE, todf=TRUE)
ggplot(dat)+geom_polygon(show.legend=FALSE, aes(x, y, group=g, fill=factor(g)), alpha=0.3)
dat1=data.frame(x=c(0, 2, 2, 0), y=c(0, 0, 1, 1)) # 原图形
# 假设对称轴是y=-x+3,转化后是-x-y+3=0
dat2=ABCxy(dat1, -1, -1, 3) # 对称的图形
ggplot()+
coord_fixed()+
geom_polygon(data=dat1, aes(x=x, y=y), fill="red")+
geom_polygon(data=dat2, aes(x=x, y=y), fill="blue")+
geom_abline(intercept=3, slope=-1)
dat1=data.frame(x=c(0, 5, 5, 0), y=c(-0.5, -0.5, 0.5, 0.5))
dat2=rotatexy(dat1, angle=seq(0, pi, length.out=8), xmiddle=0, ymiddle=0, todf=TRUE)
ggplot()+
coord_fixed()+
geom_polygon(show.legend=FALSE, data=dat2, aes(x=x, y=y, group=g, fill=factor(g)), alpha=0.2)
img=image_read("###图片spiderman.png") # 从https://github.com/githubwwwjjj/plothelper/blob/master/spiderman.PNG下载图片
# 保存一种或几种颜色并把其他部分变成黑白。由color指定颜色,如果color="click",则可在图片上点选。fuzz是要保留的颜色离指定的颜色有多近。比如,当color="red"并且fuzz=0时,只有红色会被保留下来;但若设fuzz=20,则接近红色的颜色也会被保留下来。fuzz的值域是0至100。
image_keep_color(img, color="red", fuzz=20)
# 根据灰度重新着争(实际是调用了scales::col_numeric),n是指定要保留几种颜色,最大是256。
image_col_numeric(img, palette=c("orangered", "blue", "green"), n=100)
# 调整hsv的值。本例是先把s的值rescale到一个值域中,再利用S曲线调整v的值。其他用法见英文说明。
image_modify_hsv(img, rescale_s=c(0.5, 0.8), fun_v=list("s", c1=-2, c2=2))
# 调整rgb的值。本例是用C曲线调整r的值。其他用法见英文说明书。
image_modify_rgb(img, fun_r=list("c", value=0.9))
本文地址:https://github.com/githubwwwjjj/plothelper/blob/master/README.md