Jimmy那些事儿

R_ggplot2_可视化手册

Rggplot2可视化手册

  • 每一个图层都是按照ggplot对象的先后顺序绘制的;在覆盖的问题上,可参考该顺序

输出图形

输出图形为PDF、矢量图、其他图形

width与height 默认单位为 英寸;

  • ggsave(filename, plot=last_plot, device=NULL, path=NULL, scale=1, width=NA, height=NA, units=””, dpi=300, limitsize=TRUE,…) :保存图形
    • 使用ggsave时无需打印ggplot对象,并且在创建过程中若出现错误也无需手动关闭设备

filename : 保存的文件名

device :使用的设备; 可为 "eps","ps","tex"(pictex),"pdf", "jpeg", "tiff", "png", "bmp", "svg", "wmf"(windows only)

units = c(“in”, “cm”, “mm”) :可选的单位;默认为 英寸(in)

limitsize= TRUE :大小限制;若为TRUE,将不会保存大于50 $\times$50 英寸的图形

  • 使用传统方法调用时可能出现的问题
    • 在使用某个脚本来创建图形的过程中抛出一个错误,则R可能无法执行到dev.off() ,并可能停留在设备pdf/png等仍然开启的状态。
    • 当这种情况发生时,直到你手动调用dev.off() 之前,pdf/png文件将无法用程序正常打开


PDF

  • 使用ggplot2的语法ggsave() :保存使用ggplot() 创建的最后一幅图形
    • ggsave无法用于创建多页图形
1
2
3
4
ggplot(mtcars, aes(x=wt, y=mpg)) + geom_point()
## 默认单位为英寸,但可以修改
ggsave("myplot.pdf", width=8, height=8 ,units="cm")

可能会出现字体无法匹配的情况,可通过添加 useDingbats=FALSE 来处理

1
2
3
4
> pdf("", useDingbats=FALSE)
>
> ggsave("", useDingbats=FALSE)
>
  • 打开设备 — 绘制图形 — 关闭图形设备(适用于R中大多数图形,包括ggplot2 和 lattice绘制的图形)
    • 绘制多幅图形,希望每一幅占据一页

对ggplot调用print,确保这段代码即使在一段脚本中也能调用

1
2
3
4
5
6
7
8
9
# 打开设备
pdf("myplot.pdf", width=4, height=4)
# 绘制图形
plot(mtcars$wt, mtcars$mpg)
print(ggplot(mtcars, aes(x=wt, y=mpg)) + geom_point() ) # 对ggplot调用print,确保这段代码即使在一段脚本中也能调用
# 关闭设备
dev.off()


矢量图

  • eps & svg格式
1
2
3
4
5
6
7
## 使用ggsave
ggsave("myplot.svg", width=, height=, units="")
## 常规方法
svg("myplot.svg", width=, height=)
plot()
dev.off()
  • wmf : Windows图元文件
    • 不支持透明
1
2
3
4
5
6
7
# ggsave
ggsave("myplot.wmf")
# 常规方法
win.metafile("")
plot();
dev.off()


位图

  • png / tiff

默认单位为 像素 ,默认的输出分辨率为72像素(pi);这一分辨率适合在屏幕上显示,但在打印时会显得模糊;

  • 对于高质量的打印输出,分辨率至少应该在 300ppi

使用ggsave()中的参数虽名为dpi, 但它实际上控制的是每英寸的像素数(pixels per inch ,ppi) ,而非每英寸的点数(dots per inch, dpi)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
ggplot(mtcars, aes(x=wt, y=mpg)) + geom_point()
ggsave("myplot.png", width=4, height=4, units="cm", dpi=300)
### 传统方法-----------------------------------------------------------
# 默认单位为 像素
png("filename.png", widht=400, height=400)
plot()
dev.off()
# 输出多幅图形,可在文件名后加入 %d
png("myplot-%d.png", widht=400, height=400)
plot()
print(ggplot(mtcars, aes(x=wt, y=mpg)) + geom_point() )
dev.off()
## ----修改分辨率--------
ppi <- 300
# 计算一幅4英寸 × 4英寸 300ppi图像的高度和宽度(以像素为单位)
png("myplot.png", width=4*ppi, height=4*ppi, res=ppi)
plot(mtcars$wt, mtcars$mpg)
dev.off()


图形的默认属性

参数 默认值 图形
position = “stack” geom_histogram
position_dodge() 0.9
position = “dodge” geom_bar
width = 0.9 geom_bar
size = 5 geom_text
size = 2 geom_point
scales = “fixed” facet_grid
bins = 30 stat_bin2d
method = loess stat_smooth
level = 0.95 stat_smooth

条形图

  • width =0.9
  • position = position_dodge(0.9)

文本标签

  • size = 0.9; size= rel(0.9)


描述数据分布

直方图

  • geom_histogram():映射一个连续变量到参数x

bins = n;组的数量(即出现n条柱子

binwidth = n ;组距宽度,(看做分隔范围的大小;表示每个柱子的宽度

position = “stack” (默认);位置调整

  • position= “identity” :不做任何调整
  • position= “dodge” :避免重叠,并列排放;
1
2
ggplot(mtcars, aes(x=wt)) + geom_histogram(bins=30, binwidth=0.3)
# bins=30 (默认);


分组直方图

多组数据的直方图;geom_histogram()

分面 - facet_grid/wrap

  • faect_grid(smoke.~ , scales = “free”, position=)

smoke ~ . :一列多行,根据变量smoke进行分面为n行

. ~ a # 一行多列,根据变量a进行分面为n列

a ~. # 一列多行,根据变量a进行分面n行

a~b # 多行多列

.~a+b / a+b~. # 多个变量的多个水平在行/列上(或同时)

scales = “fixed” (默认) ; 标度控制;即所有面板中x/y标度相同

scales = “free” ;x/y每个面板的标度都可以变化; 自由标度,用于发现更多的细节

scales = “free_x” / “free_y”

  • facet_wrap(~a, ncol=n)
    • 处理单个多水平变量时更适用,因为可以自定义行列数;
    • 此时结合 scales=”free” 更容易看出图形的趋势

~ a, ncol=n

~a, nrow=n

1
2
3
4
library(MASS) # 为了使用数据
# 使用smoke作为分面变量
ggplot(birthwt, aes(x=bwt)) + geom_histogram(fill="white", color="black") + facet_grid(smoke~.)
  • 分面标签:分面绘图有一个问题:即分面标签只有0和1,且没有指明这个标签变量smoke的取值;因此需要修改标签,即修改因子水平的名称
    1. 列出现有的因子水平 (因为分面没有指明这个标签的取值,重要)
    2. 依据相同的顺序赋予新的名字
1
2
3
4
5
6
7
8
9
10
11
birthwt1 <- birthwt # 复制一个数据副本
birthwt1$smoke <- factor(birthwt1$smoke); levels(birthwt1$smoke);
# 依据相同的顺序赋予新的名字
birthwt1$smoke <- factor(birthwt1$smoke, levels=c("0","1"), labels=c("No Smoke","Smoke"))
## 亦可以用 plyr::revalue 进行
library(plyr)
birthwt1$smoke <-revalue(birthwt1$smoke, c("0"="No Smoke", "1"="Smoke"))
# 重新作图
ggplot(birthwt1, aes(x=bwt)) + geom_histogram(fill="white", color="black") + facet_grid(smoke~.)


  • 分面y轴刻度:可选择根据不同面板自动调整标度;选择 scales="free"
    • 可以单独设定分面y轴/x轴的标度;但这种设定根据分面的形式而有所不同
      1. smoke ~ . :一列多行,此时x轴是固定的;此时 scales="free"等价于scales="free_y"
      2. . ~ smoke:一行多列,此时y轴是固定的;此时 scales="free"等价于scales="free_x"
1
2
# 因分面的形式为一行多列,故x轴是固定的;y轴标度自由变换
ggplot(birthwt1, aes(x=bwt)) + geom_histogram(fill="white", color="black") + facet_grid(race~., scales="free")


分组 - fill

将分组变量映射给 fill;此处分组变量必须是 因子型 或 字符型 向量

1
2
3
4
5
# 因子化
birthwt1$smoke <- factor(birthwt1$smoke)
# 将smoke映射给fill,取消条形 [堆叠],并使图形半透明
ggplot(birthwt1, aes(x=bwt, fill=smoke)) + geom_histogram(position = "identity", alpha=0.4)


密度曲线

核密度曲线是基于样本数据对总体分布做出的一个估计。

曲线的光滑程度取决于核函数的带宽:带宽越大,曲线越光滑

  • geom_density():映射一个连续变量到x;
    • 绘制的为封闭的多边形
1
2
## 绘制核密度曲线
ggplot(faithful, aes(x=waiting)) + geom_density()


开放的密度曲线

  • geom_line(stat=”identity”):绘制没有两侧与底部线段的核密度曲线
1
2
3
# 使用 expand_limits() 函数扩大y轴范围以包含0点
ggplot(faithful, aes(x=waiting)) + geom_line(stat="identity") + expand_limits(y=0)


分组密度曲线



频数多边形

频数多边形传递的信息类似直方图

  • geom_freqploy()

binwidth= n ;设定每组的组距(即宽度)

1
2
3
4
5
6
# 通过binwidth参数控制频数多边形的组距
ggplot(faithful, aes(x=waiting)) + geom_freqploy(binwidth=4)
# 通过直接设定每组组距将数据dx轴范围切分为特定数据的组
binsize <- diff(range(faithful$waiting))/15
ggplot(faithful, aes(x=waiting)) + geom_freqpoly(binwith = binsize)


箱线图

  • geom_boxplot():分别映射一个连续型变量一个离散型变量到 y 和 x ;
    • 绘制单组数据的箱线图时,必须给x参数映射一个特定的取值;可以将其设为1

width = ;修改箱线图的宽度

outlier.size = ;设置异常值的大小

outlier.shape = ;设置异常值的形状

notch= TRUE ; 显示槽口(槽口(notch)的目的是易于比较各组数据的中位数的差异;)

1
2
3
4
5
6
7
library(MASS) # 为了使用数据
# 使用factor将数值型变量转为离散型
ggplot(birthwt, aes(x=factor(race), y=bwt)) + geom_boxplot()
# 绘制单组数据箱线图,可令x=1
ggplot(birthwt, aes(x=1, y=bwt)) + geom_boxplot() + scale_x_continuous(breaks =NULL) + theme(axis.title.x=element_blank())


添加均值

  • stat_summary():
1
2
3
library(MASS) # 为了使用数据
ggplot(birthwt, aes(x=factor(race), y=bwt)) + geom_boxplot()
+ stat_summary(fun.y="mean", geom="point", shape = 23, size = 3, fill = "white")


常规图形

条形图、折线图、面积图、散点图

条形图

  • geom_bar(stat=”identity”) :一列数据表示条形在x轴上的位置,另一列数据表示每个条形在y轴上对应的高度

    • 当x为连续型变量,通过factor() 转为离散型变量

    当x是连续型(数值型)变量时,ggplot不是只在实际取值处绘制条形,而是将在x轴上结余最大值和最小值之间所有可能的取值处绘制条形

fill = ; 条形的填充色

color = ;添加并框线,并指定颜色

size = ;用来控制边框线宽度的参数,单位是毫米;(当设定了边框线颜色color)

position = “”

stack - 堆叠;fill - 堆叠并标准化为1; dodge - 分组条形图; jitter - 扰动; identity - 不做调整

width= ;条形的宽度

最大宽度为1

簇状条形图组内的条形间距为0

1
2
library(gcookbook)
ggplot(pg_mean, aes(group, weight)) + geom_bar(stat="identity")


条形图 - 簇状条形图

并排展示的条形图;

若分类变量个水平的组合中有确实项,绘图的条形会略去不进行绘制,并将条形自动扩充到相应的位置(即宽度变宽)

  • 分类变量映射到fill,并运行geom_bar(position=”dodge”)

position=”dodge” 是默认参数0.9的position_dodge()的缩写;即默认组间宽度为0.9

1
2
ggplot(cabbage_exp, ase(Date, Weight, fill=Cultivar)) +
geom_bar(position="dodge", stat="identity")


条形图 - 频数

  • geom_bar(),同时不映射任何变量到y参数
    • 当x为连续变量时,会得到一张直方图

stat = “bin” (默认);该操作会自动计算每组变量对应的频数

1
2
ggplot(diamonds, aes(cut)) + geom_bar()
# 等价于使用 geom_bar(stat="bin")


条形图 - 正负分别着色

  • 创建一个对取值正负情况进行标识的变量pos
  • 将该变量作为映射给fill
  • 通过scale_fill_manual(values=c(), guide=FALSE) :指定正负条形图的颜色,去掉图示
1
2
3
4
5
6
7
library(gcookbook)
csub <- subset(climate, Source=="Berkely" & Year >= 1900)
cusb$pos <- cusb$Anomaly10y >= 0 # 创建一个标识变量
# 将该变量映射给分组变量fill
ggplot(csub, aes(Year, Anomaly10y, fill=pos)) +
geom_bar(stat="identity", position="identity") # 令position="identity" 可以避免系统因对负值绘制堆积条形图而发出警告信息


条形图 - 宽度与间距

  • 通过geom_bar()的width 控制条形的宽度
    • 运行geom_bar(width=0.9)时,每组条形将在x轴上占据0.9个单位宽度
    • 运行position_dodge(width=0.9)时,会自动调整图形位置,使每个条形的中心恰好位于当每组条形宽度为0.9,且组内条形紧贴在一起时的位置

width=0.9 (默认);较窄的可设为0.5;最大宽度为1

簇状条形图组内的条形间距为0;若希望增加组内条形的间距

  1. 将widht 设定的小一点
  2. 并令 position_dodge的取值大于 width; position_dodge(width=0.9) 默认
1
2
3
# 簇状条形图 - 组内间距
ggplot(cabbage_exp, aes(Date, Weight, fill=Cultivar)) +
geom_bar(stat="identity", width=0.5, position=position_dodge(0.7))


条形图 - 堆积条形图

  • 使用geom_bar() ,并映射一个变量给填充色参数fill
    • 通过guides调整图例顺序
    • 通过order=desc() 来调整堆叠顺序
1
2
3
4
5
6
ggplot(cabbage_exp, aes(Date, Weight, fill=Cultivar)) +
geom_bar(stat="identity") +
gudies(fill=guide_legend(reverse=TRUE)) # 调整图例顺序
ggplot(cabbage_exp, aes(Date, Weight, fill=Cultivar, order=desc(Cultivar))) + # 调整堆叠顺序
geom_bar(stat="identity")


条形图 - 百分比堆积条形图

  • 先对每组条形对应的数据标准化为100%格式; ddply() 、 transform()
  • 对之后的结果绘制堆积条形图
1
2
3
library(gcookbook)
ce <- ddply(cabbage_exp, "Date", transform, percent_weight=Weight/sum(Weight)*100) # ddply 根据指定的变量Date进行分组,并对各组执行transfrom操作
ggplot(ce, aes(Date, percent_weight, fill=Cultivar)) + geom_bar(stat="identity")


Cleveland图

使用Cleveland点图来替代条形图以减少图形造成的视觉混乱并使图形更具可读性

  • geom_point()
    • 通过reorder():实现排列的自定义
      • reorder(name,avg) :该命令会先将name转化为因子,然后根据avg对其进行排序
      • 为了使图形效果更好,可删除垂直网格线,并将水平网格线改为虚线
    • 涉及根据两个及以上变量进行分组与排序时,只能分步实现
1
2
3
4
5
6
7
8
library(gcookbook)
tophit <- tophitters2001[1:25, ] # 取出前25个数据
ggplot(tophit, aes(x=avg, y=name)) + geom_ponit()
# 调整因子顺序,并调整外观
ggplot(tophit, aes(x=avg, y=reorder(name, avg))) +
geom_point(size=3) + theme_bw() +
theme(panel.grid.major.x=element_blank(), panel.grid.minor.x=element_blank(),panel.gird.major.y=element_line(color="grey60", linetype="dashed"))
  • geom_segment():绘制数据点为端点的线段;
    • 需要设定x /y /xend /yend 四个参数
1
2
3
4
ggplot(tophit, aes(x=avg,y=name)) +
geom_segment(aes(yend=name, xend=0, color="grey50")) +
geom_point(size=3, aes(color=lg)) +
scale_color_brewer(palette="Set1", limits=c("NL","AL"))


环状图形

饼图实际上就是柱状图,只不过是使用极坐标而已,柱状图的高度,对应于饼图的弧度

  • coord_polar(theta = “x”, start = 0, direction = 1): 非笛卡尔坐标;使用环形图
    • 根据数据源的不同有不同的做法:
      • 长格式,映射的为列中某个变量的频数
      • 宽格式,映射为某个列中具体的值(同Excel,具体的值已经经过计算)
    • 先制作堆积条形图(1. 堆积条形图; 2. 簇状条形图)

theta: variable to map angle to (x or y)
start:offset of starting point from 12 o’clock in radians
direction, 1, clockwise; -1, anticlockwise

  1. 长格式
1
2
3
4
5
6
7
8
9
## 数据源为长格式,y值为cyl列的频数,而非cyl中列的值
# 堆叠条形图
pie <- ggplot(mtcars, aes(x = factor(1), fill = factor(cyl))) + # factor(1) 表示将y分为1组
geom_bar(width = 1) # width>=1,中心的白点会去掉
pie + coord_polar(theta = "y")
# 簇状条形图
cxc <- ggplot(mtcars, aes(x = factor(cyl))) +
geom_bar(width = 1, colour = "black")

geom_bar() 中 width>=1,中心的白点会去掉

  1. 宽格式
    • ggplot(x=””) ;x为空,并且不要指定group
    • 若x = colname ,饼图的长度(离圆心的距离)会根据比例不同而不同
1
2
3
4
5
6
7
8
9
10
11
12
13
14
df <- data.frame(
variable = c("does not resemble", "resembles"),
value = c(20, 80)
);df
variable value
1 does not resemble 20
2 resembles 80
ggplot(df, aes(x = "", y = value, fill = variable)) + # x为空,y为具体的值,fill为填充色变量 [x必须为空格,即作为分组变量;使之堆叠在一个系列上]
geom_bar(stat="identity",width = 1) +
scale_fill_manual(values = c("red", "yellow")) +
coord_polar("y") +
labs(title = "Pac man")


1
2
3
4
5
6
7
8
9
10
11
12
+ coord_polar(theta="x", direction=1, start=0 ) # 绘制饼图/雷达图
# direction= 1,顺时针,-1,逆时针 start=0 12点钟弧度的起点偏移量
# 地图投影
library(mapproj)
coord_map
# 环形图
library(gcookbook)
ggplot(wind, aes(x=DirCat, fill=SpeedCat)) +
geom_histogram(binwidth=5, origin=-7.5) +
coord_polar() + scale_x_continuous(limits=c(0,360))


原始图形

1
2
3
4
5
6
library(ggplot2)
dt = data.frame(A = c(2, 7, 4, 10, 1), B = c('B','A','C','D','E'))
p = ggplot(dt, aes(x = "", y = A, fill = B)) +
geom_bar(stat = "identity") +
coord_polar(theta = "y") ## 把柱状图折叠成饼图(极坐标)
p

去除饼图中心的杂点

1
2
3
4
5
6
library(ggplot2)
dt = data.frame(A = c(2, 7, 4, 10, 1), B = c('B','A','C','D','E'))
p = ggplot(dt, aes(x = "", y = A, fill = B)) +
geom_bar(stat = "identity", width = 1) + ## width >= 1 时中心的杂点将消失
coord_polar(theta = "y")
p

去除饼图旁边的标签、刻度须线

1
2
labs(x = "", y = "", title = "") +
theme(axis.ticks = element_blank()) ## 把左上角多出来的“小胡子”去掉

图例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 去掉图例的标题,并将图例放到上面
+ theme(legend.title = element_blank(), legend.position = "top") ## 将图例标题设为空,并把土方放在上方
# 对图例的标签加上百分比
library(ggplot2)
dt = data.frame(A = c(2, 7, 4, 10, 1), B = c('B','A','C','D','E'))
myLabel = as.vector(dt$B) ## 转成向量,否则图例的标签可能与实际顺序不一致
myLabel = paste(myLabel, "(", round(dt$A / sum(dt$A) * 100, 2), "%) ", sep = "") ## 用 round() 对结果保留两位小数
p = ggplot(dt, aes(x = "", y = A, fill = B)) +
geom_bar(stat = "identity", width = 1) +
coord_polar(theta = "y") +
labs(x = "", y = "", title = "") +
theme(axis.ticks = element_blank()) +
theme(legend.title = element_blank(), legend.position = "top") +
scale_fill_discrete(breaks = dt$B, labels = myLabel) ## 将原来的图例标签换成现在的myLabel
p

按顺时针从大到小的顺序显示

  • 数据源的排列顺序,需要与因子的顺序相同 或者 逆序排列
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
library(ggplot2)
dt = data.frame(A = c(2, 7, 4, 10, 1), B = c('B','A','C','D','E'))
dt = dt[order(dt$A, decreasing = TRUE),] ## 用 order() 让数据框的数据按 A 列数据从大到小排序
# > levels(dt$B)
# [1] "A" "B" "C" "D" "E"
A B
10 D
7 A
4 C
2 B
1 E
myLabel = as.vector(dt$B)
myLabel = paste(myLabel, "(", round(dt$A / sum(dt$A) * 100, 2), "%) ", sep = "")
p = ggplot(dt, aes(x = "", y = A, fill = B)) +
geom_bar(stat = "identity", width = 1) +
coord_polar(theta = "y") +
labs(x = "", y = "", title = "") +
theme(axis.ticks = element_blank()) +
theme(legend.title = element_blank(), legend.position = "top") +
scale_fill_discrete(breaks = dt$B, labels = myLabel)
p

去掉白色外框上的数字

1
+ theme(axis.text.x = element_blank()) ## 白色的外框即是原柱状图的X轴,把X轴的刻度文字去掉即可

在图中加百分比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
library(ggplot2)
dt = data.frame(A = c(2, 7, 4, 10, 1), B = c('B','A','C','D','E'))
dt = dt[order(dt$A, decreasing = TRUE),]
myLabel = as.vector(dt$B)
myLabel = paste(myLabel, "(", round(dt$A / sum(dt$A) * 100, 2), "%)", sep = "")
p = ggplot(dt, aes(x = "", y = A, fill = B)) +
geom_bar(stat = "identity", width = 1) +
coord_polar(theta = "y") +
labs(x = "", y = "", title = "") +
theme(axis.ticks = element_blank()) +
theme(legend.title = element_blank(), legend.position = "top") +
scale_fill_discrete(breaks = dt$B, labels = myLabel) +
theme(axis.text.x = element_blank()) +
geom_text(aes(y = A/2 + c(0, cumsum(A)[-length(A)]), x = sum(A)/20, label = myLabel), size = 5) # 在图中加上百分比:
## x 调节标签到圆心的距离, y 调节标签的左右位置
# cunsum(A) 累计和
# [-length(A)] 删除最后一个元素
# sum(A)=24 /20 =1.2
p


分面

  • 在ggplot(aes()) 中不要指定group,其他正常即可。


生成饼环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
+ geom_bar(stat = "identity", width = 0.2) + ## 当width < 1 时饼图将变成饼环
library(ggplot2)
dt = data.frame(A = c(2, 7, 4, 10, 1), B = c('B','A','C','D','E'))
dt = dt[order(dt$A, decreasing = TRUE),]
myLabel = as.vector(dt$B)
myLabel = paste(myLabel, "(", round(dt$A / sum(dt$A) * 100, 2), "%)", sep = "")
p = ggplot(dt, aes(x = "", y = A, fill = B)) +
geom_bar(stat = "identity", width = 0.2) + ## 当width < 1 时饼图将变成饼环
coord_polar(theta = "y") +
theme_bw() +
labs(x = "", y = "", title = "") +
theme(axis.ticks = element_blank()) +
theme(legend.position = "none") +
theme(axis.text.x = element_blank()) +
geom_text(aes(y = A/2 + c(0, cumsum(A)[-length(A)]), x = sum(A)/24.5, label = myLabel), size = 5)
p

去掉饼环之外的框框和中间的坐标线

1
2
theme(panel.grid=element_blank()) + ## 去掉白色圆框和中间的坐标线
theme(panel.border=element_blank()) ## 去掉最外层正方形的框框

饼环 - geom_rect()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
library(ggplot2)
ad = data.frame(type = c("Poster", "Billboard", "Bus", "Digital"),n = c(529, 356, 59, 81))
ad$fraction = ad$n / sum(ad$n)
ad$ymax = cumsum(ad$fraction)
ad$ymin = c(0, head(ad$ymax, n = -1))
ggplot(data = ad, aes(fill = type, ymax = ymax, ymin = ymin, xmax = 4, xmin = 3)) +
geom_rect(colour = "grey30", show_guide = FALSE) +
coord_polar(theta = "y") +
labs(x = "", y = "", title = "") +
xlim(c(0, 4)) +
theme_bw() +
theme(panel.grid=element_blank()) + ## 去掉白色外框
theme(axis.text=element_blank()) + ## 把图旁边的标签去掉
theme(axis.ticks=element_blank()) + ## 去掉左上角的坐标刻度线
theme(panel.border=element_blank()) + ## 去掉最外层的正方形边框
geom_text(aes(x = 3.5, y = ((ymin+ymax)/2), label = type))


折线图

  • geom_line():分别指定一个变量映射给x和y

    • x : 常规为连续变量;(显示为日期,但格式为字符串或因子,则必须转为 as_date() 格式)

    • 若为离散型变量,需要通过factor()进行转换此时必须使用aes(group=1)以确保知道这些数据点属于同一分组,从而应该用一条折现连在一起;

      并且此时x轴的刻度值仅为因子型变量对应的分类值;若分类变量只有[1,2,4],此时x轴的刻度也仅显示[1,2,4] ,不会出现3

position = position_dodge(0.2):微调;左右移动0.2,来避免重叠

如果x变量时因子,必须同时告诉ggplot()用来分组的变量

1
2
3
4
5
6
7
8
9
# x 为连续型变量
ggplot(BOD, aes(Time, demand)) + geom_line()
# x 为离散型变量
ggplot(BOD, aes(x=factor(Time), y=demand, group=1)) + geom_line()
# 通过expand_limit() 扩展y轴的范围
ggplot(BOD, aes(Time, demand)) + geom_line() +
expand_limits(y=0) # 等价于 ylim(0,max(BOD$demand))


折线图 - 多重折线图

  • 在分别设定一个映射给x和y的基础上,再将另一个(离散型)变量映射给颜色(color)或者线型(linetype)
  • 如果x变量时因子,必须同时告诉ggplot()用来分组的变量,否则ggplot()会不知道如何将数据组合在一起绘制折线图
    • 当分组不正确时,折线图会变成锯齿状原因在于x在每个位置都对应于多个点,ggplot()误以为这些点属于同一组数据而将其用一条折现连接

当你的折线图看起来不太合理或呈现锯齿状时,是由于分组不明确,此时必须要用group明确指定分组变量

若当前数据无法实现,考虑转为长格式的数据结构

1
2
3
4
5
6
7
8
9
10
library(plyr) # 便于使用ddply()创建样本数据集
tg <- ddply(ToothGrowth, c("supp","dose"), summarise, length=mean(len))
# 将supp映射给颜色 color
ggplot(tg, aes(x=dose,y=length, color=supp)) + geom_line()
# 将supp映射给线型 linetype
ggplot(tg, aes(x=dose, y=length, linetype=supp)) + geom_line()
## x变量为因子,必须指定分组的变量
ggplot(tg, aes(x=factor(dose), y=length, color=supp, group=supp)) + geom_line()


折线图 - 添加数据标记

  • geom_point():通过点来添加标记

position = position_dodge(0.2):微调;左右移动0.2,来避免重叠

size / shape / color / fill :调整标记样式

1
ggplot(BOD,aes(Time,demand)) + geom_line() + geom_point()


折线图 - 线条样式

linetype、size、color

  • 通过将参数传递给geom_line()设置折线图对应的属性
    • 对多重折线图而言,设定图形属性会对所有折线产生影响
    • 将变量映射给图形属性会使折线具由不同的外观。可用scale_color_brewer()scale_color_manual() 来设定
1
ggplot(BOD, aes(Time, demand)) + geom_line(linetype = "dashed", size= 1, color= "blue")


折线图 - 实例

将数据转为长格式,然后分组作图,再分面

注意:当你的折线图看起来不太合理或呈现锯齿状时,是由于分组不明确,此时必须要用用group明确指定分组变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
filter(data_all, 结算日期>='2017-06-23',产品 %in% c('螺纹钢', '铁矿石')) %>%
melt(., id=c('结算日期','产品'),measure=c('平仓盈亏','持仓盈亏'), variable.name='盈亏类别',value.name='盈亏金额') %>%
ggplot(., aes(x=结算日期,y=盈亏金额, color=盈亏类别,group=(盈亏类别))) +
geom_line() +
facet_wrap(~产品, nrow=2)
# 示例数据
结算日期 产品 盈亏类别 盈亏金额
2017-06-23 铁矿石 平仓盈亏 1258.425
2017-06-23 螺纹钢 平仓盈亏 1453.010
2017-06-26 铁矿石 平仓盈亏 285.390
2017-06-26 螺纹钢 平仓盈亏 -2260.440
2017-06-27 铁矿石 平仓盈亏 2133.495
2017-06-27 螺纹钢 平仓盈亏 -2947.100
2017-08-04 铁矿石 持仓盈亏 -2781.870
2017-08-04 螺纹钢 持仓盈亏 5427.866
2017-08-07 铁矿石 持仓盈亏 2444.015
2017-08-07 螺纹钢 持仓盈亏 28933.560
2017-08-08 铁矿石 持仓盈亏 13062.565
2017-08-08 螺纹钢 持仓盈亏 10053.853

日期格式的作图

  • x轴转为指定的日期形式的字符串格式

通过format 函数可以提取任意部分的日期,包括日期、星期几

format(x, format=””)

1
2
3
4
5
6
7
8
9
with(data_source_zhibo,{
data_source_zhibo$日期 <- format(data_source_zhibo$日期,format='%m/%d') # format格式转化为后字符串格式
data_source_zhibo$首席分析师 <- factor(data_source_zhibo$首席分析师, levels=c("黄伟","夏飞龙","陈明燕","王健"))
ggplot(data_source_zhibo, aes(x=日期, y =最大并发与IP量之比, color=首席分析师,group=首席分析师)) + # 注意group=xxx
geom_line(size=0.7) +
theme_classic() +
labs(title="最大并发与IP量之比", y=NULL) +
theme(axis.text.x=element_text(angle=90, vjust=0.5),plot.title=element_text(hjust=0.5, face="bold"), panel.grid.major.y = element_line(color="grey50"))
})
  • 日期格式
1
2
3
4
library(sacles)
ggplot(data_source_zhibo, aes(x=日期, y =最大并发与IP量之比, color=首席分析师)) +
geom_line() +
scale_x_date(brekas=data_source_zhibo$日期, labels=date_format("%m%d"))


面积图

  • geom_area():绘制面积图
    • 默认情况下,面积图的填充色为黑灰色,且没有边框线;
    • 若添加边框线令 color = “black” 会使得底部有一条横线,且在起点和终点的位置有一条垂直线;此时可通过不设定color,并用geom_line()绘制轨迹线

fill / color / alpha :调整样式

1
2
3
ggplot(sunspotyear, aes(x=Year, y= Sunspots)) +
geom_area(fill="bule", alpha=0.2) +
geom_line()


面积图 - 堆积

  • geom_area():运行geom_area,并映射一个因子型变量填充色(fill)即可;
    • 图例翻转:brekas;默认情况下,图例的顺序与面积图的顺序是相反的;通过设定标度中的切分(breaks)参数来翻转堆积顺序
    • 图形堆积翻转:在aes()内部设定order=desc(col)

size = 0.2 ;在各个区域之间添加细线

alpha = 0.4 ;将填充区域设置为半透明

1
2
3
4
5
6
7
8
9
10
11
12
library(gccokbook) # 为了使用数据
ggplot(uspopage, aes(x=Year, y=Thousands, fill=AgeGroup)) + geom_area()
# 图例翻转 breaks=rev(levels(data$col))
ggplot(uspopage, aes(x=Year, y=Thousands, fill=AgeGroup)) +
geom_area(color="black", size=0.2, alpha=0.4) +
scale_fill_brewer(palette="Blues", breaks=rev(levels(uspopage$AgeGroup)))
# 翻转面积图的堆积顺序
ggplot(uspopage, aes(x=Year, y=Thousands, fill=AgeGroup, order=desc(AgeGroup))) +
geom_area(color="black", size=0.2, alpha=0.4) +
scale_fill_brewer(palette="Blues")
  • 绘制没有边框线的面积图:先绘制一个不带边框线的面积图(color=NA),然后在其顶部添加geom_line()
1
2
3
4
ggplot(uspopage,aes(Year, Thousands, fill=AgeGroup, order=desc(AgeGroup))) +
geom_area(color=NA, alpha=0.4) +
scale_fill_brewer(palette="Bluese") +
geom_line(position="stack", size=0.2)


面积图 - 百分比堆积

  • 先要计算各组对应的百分比,将该百分比列映射给y
1
2
3
4
5
6
7
8
library(gcookbook) # 为了使用数据
# 将Thousands转化为百分比
uspopage_prop <- ddply(uspopage, "Year", transform, Percent = Thousands / sum(Thousands)*100) # 对每一行做运算
# 映射与绘制
ggplot(uspopage_prop, aes(Year, Percent, fill=AgeGroup)) +
geom_area(color="black", size=0.2, alpha=0.4) +
scale_fill_brewer(palette="Blues", breaks=rev(levels(uspopage_prop$AgeGroup)))


添加置信域

  • 阴影的置信域:运行geom_ribbon(),之后分别映射一个变量给 ymin 和 ymax
1
2
3
4
5
6
7
library(gcookbook) # 为了使用数据
clim <- subset(climate, Source=="Berkeley", select=c("Year","Anomaly10y","Unc10y"))
# 将置信域绘制为阴影
ggplot(clim, aes(x=Year, y= Anomaly10y)) +
geom_ribbon(aes(ymin=Anomaly10y-Unc10y, ymax=Anomaly10y+Unc10y),alpha=0.2) +
geom_line() # geom_ribbon 绘制的顺序在geom_line()之前是为了使折线绘制在阴影区域上面的图层,使折线更清晰
  • 虚线的置信域:运用多个geom_line(),分别将上下边界映射给y
1
2
3
4
ggplot(clim, aes(Year, Anomaly10y)) +
geom_line(aes(y=Anomaly10y-Unc10y), color="gery50", linetype="dotted") +
geom_line(aes(y=Anomaly10y+Unc10y), color="gery50", linetype="dotted") +
geom_line()



散点图

  • geom_point():分别映射一个变量到x和y

shape = 3;设置不同的的点型

size = 2(默认); 设置点的大小

color = ;点的轮廓色

fill = ;填充色;


散点图 - 分组

  • 分组变量映射给点型(shape)和颜色(color)属性
    • 分组变量必须是分类变量(即必须是因子型或字符串型的向量),可用factor转化后进行映射
1
2
3
4
ggplot(heightweihgt, aes(ageYear, heightIn, color=sex)) + geom_point()
# 将一个变量同时映射给 shape 和 color
ggplot(heightweihgt, aes(ageYear, heightIn, shape = sex, color=sex)) + geom_point()
  • 自定义分组变量的点型与颜色
    • scale_shape_manual(values=c(1,2))
    • scale_color_brewer() / scale_color_manual(values=c())

当填充色为NA时,会形成一个空心的形状


散点图 - 连续型变量

当变量超过2个时,必须将它们映射到其他图形属性上,比如点的大小和颜色;

人类对于感知空间位置的微小变化很擅长,但对于图形颜色和大小的变化不敏感;因此,只有当一个变量不需要高精度的解释时,它才被适合映射给图形的大小和属性

  • size= 2 ;控制大小;将某个变量映射给size属性时,最好避免将其他变量映射给shape属性;因为不同点型的点大小很难相互比较
  • scale_size_continuous(range=c()):修改数据点大小的变化范围;默认情况下为1~6ms
    • 当映射给大小(size)属性时,绘制的图形结果往往具有误导性;最大点对应的面积为最小点的36倍,但在数值上仅3.5倍;
    • 即使修改数据点的范围,但由于点的大小与点的直径或面积是非线性的,所以这个表示值依然不精确
  • color / fill :对于大多数点型,通过color属性设定颜色
    • 点型21-25 除了实心区域,还有边框线,此时可通过fill来控制
    • 当数据点颜色较浅时,带框线的点型就会很有用
1
2
3
ggplot(heightweight, aes(ageYear, heightIn, fill=weightLb)) +
geom_point(shape=21, size=2.5) +
scale_fill_gradient(low="black",high="white", breaks=seq(70,170,20), gudie =guide_legend())


散点图 - 图形重叠

  1. 图形的重叠度较低时

    • 较小(size)的数据点
    • 不会遮盖其他数据点的点形(例如1号空心圆)
  2. 图形重叠度较高时

    • 使用半透明(alpha)的点
    • 数据分箱(bin),并用矩形表示(适用于量化分析) stat_bin2d()

    stat_bin2d() 函数分别在x轴和y轴方向上将数据分隔为30个组,总计900个箱子

    通过scale_fill_gradient() 设定数据点的颜色,并制定最小色阶low 和最大色阶high

    • 默认情况下,图例中不包括最小值,因为颜色标度的范围不是从0开始,而是以各箱中的最小非零值为起始点;若要包括零值,可调用limits参数手动这顶范围为0到最大值
    • 将数据分箱(bin),并用六边形表示hexbin::stat_binhex() (需先安装hexbin包)
    • 增加随机扰动: position_jitter() 等价于 geom_point(position=”jitter”)

    当散点图的其中一个或两个数据周对应离散型数据时,会出现重叠的情况

    默认情况下,position_jitter() 在每个方向上添加的扰动值为数据点最小精度的40%;但可通过width 和 height 进行调整

    • 使用箱线图

    当数据集对应一个离散型和一个连续型数据时,箱线图时一种比较好的展示方式

1
2
3
4
5
6
7
8
9
# 分箱 - 矩形
sp + stat_bin2d(bins=30) # 默认为30
# 分箱 - 六边形
sp + stat_binhex()
# 添加随机扰动
sql <- ggplot(ChickWeight, aes(Time, weight))
sql + geom_point(position = position_jitter(width=0.5,height=0))


散点图 - 回归拟合线

向散点图中添加线型回归拟合线

  • stat_smooth():设定method=lm 即可向散点图中添加线型回归拟合线
    • 若散点图进行了分组,并将分组变量映射给color和shape属性,则会分别添加拟合线

method = loess(默认);设置拟合的模型

loess曲线 : 局部加权多项式

method = glm, family=binomial :添加Logistic回归拟合线

lm ,线性回归

se = FALSE ;控制置信区间;若为会TRUE,会添加95%的置信域

level = 0.95 ;控制置信域的水平

color / linetype / size :控制拟合线的属性

为了突出直线,可设置点的 color 以使数据点不那么突出

fullrange=TRUE;默认为FALSE,支持外推的模型;正常情况下,loess()函数只能根据数据对应的x轴的范围进行预测

1
2
3
4
5
6
library(gcookbook)
sp <- ggplot(heightweight, aes(ageYear, heightIN))
sp + geom_point() + stat_smooth(methdo=lm)
# 99%置信域
sp + geom_point() + stat_smooth(method=lm, level=0.99)


散点图 - 根据已有模型添加拟合线

我们需要建立自己的模型,再将模型添加到散点图上

  • 无论哪种模型,只要有对应的predict() 方法,都可以用来绘制拟合线
    • lm() 与 loess() 函数对应的方法分别是 predict.lm() 和 predict.losee()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
library(gcookbook)
model <- lm(heightIn ~ ageYear + I(ageYear^2), heightweight)
model # 查看模型
# 创建一个包含变量的ageYear列,并进行插值
xmin <- min(heightweight$ageYear)
xmax <- max(heightweight$ageYear)
predicted <- data.frame(ageYear=seq(xmin, xmax, length.out=100))
# 计算变量heightIn的预测值
predicted$heightIn <- predict(model, predicted)
predicted
# 将数据点和模型预测值一起绘制
sp <- ggplot(heightweight, aex(ageYear, heightIn)) +
geom_point(color="grey40")
sp + geom_line(data=predicted, size=1)


散点图 - 添加多个模型的拟合线


散点图 - 添加模型系数


散点图 - 编辑地毯

边际地毯图本质上是一个一维的散点图,可被用于展示每个坐标轴上数据的分布情况

  • geom_rug():添加边际地毯图
1
ggplot(faithful, aes(eruptions, waiting)) + geom_point() + geom_rug()


散点图 - 标签


散点图 - 气泡图

  • geom_point() + scale_size_area() :通过这两者绘制气泡图
    • 若直接将变量GDP映射给size属性,则GDP的值被映射给了点的半径;此时变量增加一倍时,点的面积会变为原来的4倍;这并不是我们想要的
1
2
3
4
5
6
7
library(gcookbook)
cdat <- subset(contries, Year==2009 & Name %in% c("Canda", "Ireland","United Kingdom"))
# 绘制气泡图
p <- ggplot(cdat, aes(healthexp, infmortality, size=GDP)) +
geom_point(shape=21, color="blcak", fill="cornsilk") +
scale_size_area(max_size=15) # 得到一个较大的圆
  • 其他用法:当x轴和y轴均为分类变量时,气泡图可以用来表示网格点上变量值
1
2
3
4
5
6
7
8
9
10
# 对男性组和女性组求和
hec <- HairEyeColor[,,"Male"] + HairEyeColor[,,"Female"]
# 转为长格式
library(reshape)
hec <- melt(hec, value.name="count")
ggplot(hec, aes(Eye, Hari)) +
geom_point(aes(size=count), shape=21, color="black", fill="cornsilk") +
scale_size_area(max_size=20, guide=FALSE) +
geom_text(aes(y=as.numeric(Hari)-sqrt(count)/22, label=count), vjust=1, color="grey60", size=4) # 文本是灰色的,为了削弱文本的突出性,避免圆圈的展示


散点图 - 散点图矩阵



数据标签 - geom_text()

运行geom_bar() 和 geom_text() 时,需要分别指定一个变量映射给x、y和标签本身

  • geom_text()

    • 通过设定y轴的范围,使得标签在绘图区域内;geom_text(aes(y=Weight+0.1, label=Weight))

    当标签被置于顶端上方有可能使数据标签溢出绘图区域。

    • 使用标签数据时,对堆叠顺序的调整最好是通过在计算累计和之前修改因子的水平顺序

x ,y = colname ; 表示范围

label = colmame;显示的标签名

alpha =

color =

size = 5 (默认);

hjsut /vjust = 0(right/bottom) 和 1(left/top)

0,表示左对齐/底部对齐; 形同PPT的对象对齐;而非表格的左右对齐

1,表示又对齐/顶部对齐;

字符串(“left”,”right”,”middle”,”bottom”,”center”,”top”);

字符串 (“inward”,”outward”)

nudge_x=0 ; nudge_y=0 ;x轴方面,微调

1
2
3
4
5
6
7
8
9
10
11
12
13
library(gcookbook)
ggplot(cabbage_exp, aes(x=interaction(Date, Cultivar), y=Weight)) +
geom_bar(stat="identity") +
gemo_text(aes(label=Weight), vjust=1.5, color="white") # 标签在顶端下方
# vjust = -0.2 # 标签在顶端上方
# 设定标签的y轴位置使其略高于条形图顶端 —— y轴范围会自动调整
ggplot(cabbage_exp, aes(x=interaction(Date,Cultivaar),y=Weight)) +
geom_bar(stat="identity") +
geom_text(aes(y=Weight+0.1, label=Weight))
#
geom_text(aes(label=Weight), vjust=1.5, color="white", position=position_dodge(0.9), size=3) # 保持标签与条形宽度一致;因为分类间距默认为0.9



参数与外观设置

坐标轴、图例、注解、外观、分面、配色


标度 & 主题元素一览

标度变换 - scale

  1. 位置标度: scale_x_discrete() / scale_x_continuous()
  2. 颜色标度:scale_fill_xxx() / scale_color_xxx()
  3. 图例标度:

主题元素函数

?theme 可获得全部的信息

  • element_text()

face=”” # 字体格式

“bold” - 加粗 ;”italic” - 斜体 ;”bold.italic” - 粗斜体;”plain” - 无格式的

color =

size = num ; size = rel( n ) 当前字体的n倍

hjust /vjust = [0,1] # 对齐方式类同PPT的根据元素对齐

angle = [0,360]

lineheight = num # 行高

  • element_line()

linetype = [0,6]

1- solid 实线; 2-虚线 dashed;3-点 dotted;4 - 破折号 dotdash;5 - 长破折号 longdash;6-双破折号 twodash

color =

size =

  • element_rect()

linetype =

size =

color = “”

fill = “”

  • element_blank()


坐标轴

theme(axis.)

  • 坐标系

翻转

  1. coord_flip()

刻度范围 - 显示域

  1. coord_cartesian( xlim=c(), ylim=c())
  • 坐标轴

显示名称 + 外观

  1. labs(x=””, y=”” )
  2. theme(axis.title.x = element_text(…) ) # 外观设置

刻度范围 - 定义域

  1. xlim() / ylim()

  2. scale_x_discrete() / scale_x_continuous()

    limits = c(“”) / c(0,10)

  3. expand_limits(x=, y=)

刻度标签 - 显示 + 外观

  1. scale_x_discrete() / scale_x_continuous()

    breaks=c(“”) / c(0,5,10)

    labels=c(“”) / c() # 若设置了labels,必须同时指定breaks

  2. theme(axis.text.x = element_text() ) # 刻度标签外观

刻度标签 - 反转

  1. scale_x_discrete( limits=rev(levels( data$colname ))) # 离散型

  2. scale_x_reverse() # 连续型

    scale_x_reverse(limits=c(3,0)) # 反转,并设定定义域

刻度线

  1. theme(axis.ticks = element_blank() ) # 刻度线位置等于标签显示的位置

x / y 轴缩放比例

  1. coord_fix() :使得x/y轴为1:1
  2. 通过scale_x/y_continuous(breaks=seq(0,420,30) )

坐标轴直线

  1. theme(axis.line = element_line(…))


交换x轴和y轴

  • coord_flip() :翻转坐标轴


坐标轴值域 - 连续型

ylim() 是 scale_y_continuous() 的简便写法,两者应避免同时出现;若要设置除值域外的其他属性,则一定要统计使用scale_y_continuous()

ggplot2中有2两种方式修改坐标轴值域

  1. 修改标度:任何在范围以外的数据都会被移除;即超出的数据不仅不糊被展示,而且会被完全移出处理的数据范围,并且会使图形改变
    • ylim() / scale_x_discrete() / scale_x_continuous()
  2. 应用一个坐标变换:数据不会被修剪;它只是放大或缩小到指定的范围
    • coord_cartesian(ylim=c())
1
2
3
4
5
6
p <- ggplot(PlantGrowth, aes(group, weight)) + geom_boxplot()
p + ylim(0, 10) # 设置值域的一种方法
p + scale_y_continuous(limits=c(0,10), breaks=c(0,5,10)) # 设置值域,并设定了刻度线放置在0,5,10的位置
p + expand_limits(y=0) # 通过单向扩展值域,但不能用它来缩减值域


坐标轴 - 项目的顺序

  • 离散型变量排序的翻转:scale_x_discrete(limits=rev(levels(…)))

limits= c(“trt1”,”trt2”) ;指定显示的项目与顺序

  • 连续型变量排序的翻转:scale_x_reverse()
1
2
3
4
5
6
7
8
9
# 离散型变量排序翻转
p <- ggplot(PlantGrowth, aes(group, weight)) + geom_boxplot()
p + coord_flip() +
scale_x_discrete(limits=rev(levels(PlantGrowth$group)))
# 连续型变量排序翻转
p + scale_y_reverse()
p + scale_y_reverse(limits=c(3,0)) # 翻转并设定值域


坐标轴 - 缩放比例

x / y 的比例

  • coord_fixed():得到x轴和y轴之间 1:1 的缩放结果
    • 所指的1:1缩放是单位长度表示的数值范围是1:1,从而形成正方形的绘图区域
1
2
3
4
5
6
7
library(gcookbook) # 为了使用数据
sp <- ggplot(marathon, aes(Half, Full)) + geom_point()
sp + coord_fixed()
sp + coord_fixed() +
scale_y_continuous(breaks=seq(0,420,30)) +
sacle_x_continuous(breaks=seq(0,420,30)) # 使x与y轴两者的刻度线相同


坐标轴 - 刻度线

刻度线 - 位置

  • scale_x_continuous(breaks=):指定显示的刻度线

breaks=c(“4,4.25, 4.5”) :离散型

brekas=seq(0,40,10) :连续型


刻度线和标签 - 移除

对于连续型坐标轴,ggplot()会在每个breaks值的位置放置刻度线、刻度标签和主网格线;

对于离散型坐标轴,这些元素会出现在每个limits的位置

  • theme(axis.text.y=element_blank()):移除标签
  • theme(axis.ticks=element_blank()):移除刻度线


坐标轴 - 刻度标签

设置与修改文本

  • 通过标度scale_x_discrete/continuous中的breaks和labels进行赋值
  • 随ggplot2安装的scales包自带了一些内建的格式化函数:
    • comma() :在千、百万、十亿等位置向数字添加逗号
    • dollar():添加一个美元符号并舍入到最近接的美分
    • percent():乘以100,舍入到最接近的整数值,并添加一个百分号
    • scientific():对大数字和小数字给出科学计数法都表示, 如3.30e+05
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
library(gcookbook)
hwp <- ggplot(heightweight, aes(ageYear, heightIn)) + geom_point() +
scale_y_continuous(breaks=c(50,56,60,66,72), labels=c("Tiny","Really\nshort","Short","Medium","Tallish"))
## 以某种格式存储标签
# 身高格式,显示为5'6'',通过自定义函数来完成
footinch_formatter <- function(x){
foot <- floor(x/12)
inch <- x %% 12
return(paste(foot, "'",inch,"\"", sep=""))
}
footinch_formatter(56:64)
[1] "4'8\"" "4'9\"" "4'10\"" "4'11\"" "5'0\"" "5'1\"" "5'2\""
[8] "5'3\"" "5'4\""
hwp + sacle_y_continuous(labels=footinch_formatter)
# 将时间测度转化为HH:MM:SS或其他的格式
timeHMS <- function(x){
h <- floor(x/60)
m <- floor(x %% 60)
s <- round(60*(x %% 1)) # 舍入到最接近的秒数
lab <- sprintf("%02d:02d:02d",h,m,s) # 格式化字符串为HH:MM:SS的格式
lab <- gsub("^00:","", lab) # 如果开头存在00:,则移除
lab <- gsub("^0", "", lab) # 如果开头存在0,则移除
return(lab)
}


坐标轴 - 刻度标签的外观

旋转、对齐、大小、颜色等

  • theme(axis.text.x=element_text(angle=90, hjust=1, vjust=0.5)):旋转标签

element_text()的其他文本属性

color / size / face / family

size = rel(0.8) :表示当前字体大小的0.9倍;


坐标轴 - 坐标轴标签(名称)

坐标轴标签 - 修改

  • labs(x=””, y=”” ) :修改坐标轴的标签
  • xlab / ylab(“”) :修改坐标轴的标签


坐标轴标签 - 移除

  • theme(axis.title.x=element_blank()):移除坐标轴标签,且不会为其留出空间
  • lab(x=””) :只是将其设置为空白


坐标轴标签 - 外观

  • theme(axis.title.x = element_text()):


坐标轴 - 直线

  • theme(axis.line=element_line(clolor=”black”)):沿坐标轴显示直线

lineend = “square” :可将坐标轴直线边界的末端进行重叠

若最初使用的主体在绘图区域的周边就有一条线(如theme_bw()),需要同时重置参数panel.border

1
2
p + theme_bw() +
theme(panel.border=element_blank(), axis.line=element_line(color="black"))


对数坐标轴

  • scale_x_log10() / scale_y_log10() :设置对数坐标轴
1
2
3
4
5
6
library(MASS) # 使用数据
p <- ggplot(Animals, aes(x=body, y=brain, label=rownames(Animals))) +
geom_text(size=3)
# 使用对数坐标轴
p + scale_x_log10() + scale_y_log10()
  • scales包中的 trans_format()刻度标签使用指数计数法
1
2
3
4
5
6
7
8
# 使用指数计数法的刻度标签
library(scales)
p + scale_x_log10(breaks = 10^(-1:5), labels=trans_format("log10", math_format(10^.x))) +
scale_y_log10(breaks = 10^(0:3), labels=trans_format("log10", math_format(10^.x)))
# 使用自定义的变换
p + scale_x_continuous(trans= log_trans(), breaks=trans_breaks("log", function(x) exp(x)), labels=trans_format("log", math_format(e^.x))) +
scale_x_continuous(trans= log_trans(), breaks=trans_breaks("log2", function(x) 2^x), labels=trans_format("log2", math_format(2^.x)))
  • annotation_logticks():添加刻度


坐标轴 - 日期

ggplot2可以处理两类时间对象:日期对象(类为Date的对象),日期时间对象(类为POSIXt的对象)

使用 日期格式的函数,对象必须为日各

  • as.Date / as_date():注意转化为日期格式
  • scale_x_date():特定的日期格式坐标轴函数(Date格式)
  • scale_x_datetime():特定的时间格式坐标轴函数(POSIX格式)
  • scale_x_time() :特定的时间格式的坐标轴函数(HMS格式)

breaks:

date_breaks:两者同时出现时,以date_breaks为准;

labels = 指定具体的标签内容

date_labels= “%Y/%m/%d %H:%M:S” :指定标签的格式;

  • 两者同时出现时,以date_labels为准;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
library(gcookbook)
ggplot(economics, aes(date, psavert)) + geom_line()
# 设置需要的日期序列
econ <- subset(economics, date >= as.Date("1992-05-01") & date < as.Date("1993-06-01") ) # 选取子集
# 基本图形
p <- ggplot(econ, aes(date, psavert)) + geom_line()
# 指定一个日期向量为分割点
datebreaks <- seq(as.Date("1992-06-01"), as.Date("1993-06-01"), by="2 month")
# 使用分割点并旋转文本
p + scale_x_date(breaks=datebreaks) +
theme(axis.text.x = element_text(angle=30, hjust=1))
# 指定格式 - scales::date_format
library(scales)
p + scale_x_date(breaks=databreaks, labels=date_format("%Y %b")) +
theme(axis.text.x = element_text(angle=30, hjust=1))
##----------------------------------
#日期格式
df <- data.frame(
date = Sys.Date() - 0:29,
count = runif(30))
tu <- ggplot(df, aes(date, count)) +geom_line()
## 下面两个语句的画图结果都是同一个图
#1、在lables和date_labels同时出现的情况下,系统会优先使用date_labels设置
#2、在时间设置方面,date_labels,以及date_breaks 设置要比 labels和breaks设置要简洁得多。
tu+scale_x_date(breaks=as.Date(c("2016-06-06","2016-06-13","2016-06-20","2016-06-27")),
labels=c("06-06","06-13","06-20","06-27"),date_labels="%y/%m/%d")
tu+scale_x_date(date_labels="%y/%m/%d")


结合scales包完成分隔与格式

  • date_breaks(width=”1 month”)

截断内容除了days,以外还可以用“auto”, “secs”, “mins”, “hours”, “weeks”等对数据进行分割显示。

  • date_format(format=”%y-%m-%d”)
1
2
3
4
5
6
# 时间格式
df <- data.frame(
date = as.POSIXct(Sys.Date() - 0:29),
count = runif(30))
tu + scale_x_datetime(breaks=date_breaks("10 days"),labels=date_format("%m/%d") )


作图指定的坐标轴日期格式

axis.POSIXct {graphics}:Functions to plot objects of classes “POSIXlt”, “POSIXct” and “Date” representing calendar dates and times.

  • axis.POSIXct(side, x, at, format, labels = TRUE, …)
  • axis.Date(side, x, at, format, labels = TRUE, …)

    x, at:A date-time or date object.

    side :See axis.
    format:See strptime.



坐标轴 - 相对时间

  • 方法一:手动指定跟个点和标签: scale_x_continuous(breaks=c(), labels=c())
  • 方法二:自定义一个格式刷函数



图例

图例 - 概览;图例是根据aes美学来进行绘制的

theme属性是用来修改外观的

  • 图例的整个控制

存在与否

  1. guides(fill=FALSE)
  2. theme(legend.position=”none”)

位置相关

  1. theme(legend.position=”” ) : left / right / bottom / top
  2. theme(legend.position=c(0, 1) ) :
  3. theme(legend.justification=c(0,1) ) :

整体背景

  1. theme(legend.background = element_rect() )
  • 图例的细节部分

内部顺序

  1. guides( fill=guide_legend(reverse=TRUE )
  2. scale_fill_discrete(limits=c(“”))

标题

  1. labs(fill=”name”) / labs(fill=NULL)
  2. theme(legend.title = element_text()) / element_blank()

文本标签

  1. scale_fill_discrete(labels=c())
  2. theme(legend.text = element_text())

图例符号

  1. theme(legend.key = element_rect())

宽度、列数、方向等

  1. guides( fill = guide_legend( … ) )

keywidth = 5 ;宽度

direction = “horizontal” / “vertical”

nrow / ncol = 2 ;图例内部的行列数


图例 - 添加

同一图形中添加图例

不同图形中添加图例:

  • scalexxx 需紧跟在该几何对象geom_之后
  • 若希望图例的合并,则需要使用同一种标度;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 同一图中出现三种颜色,并显示图例
ggplot(dd) + geom_line(aes(x=fecha, y=value, colour=variable)) +
scale_colour_manual(values=c("red","green","blue"))
#----------------------
# 不同图形中添加图例
ggplot(qian_all_data_top22,aes(x=factor(format(as_date(日期),format="%m-%d")))) +
geom_bar(aes(y=IP总量,fill="red"),stat="identity",width=0.5) +
scale_fill_manual(breaks="red",fill="#95B3D7") + # scale紧跟在几何对象之后
# ylim(c(2000,max(qian_all_data_top22$IP总量))) + expand_limits(y=0)
geom_line(aes(y=最大并发数,group=1,color="black")) +
scale_color_manual(breaks="black",values="black") +
geom_point(y=qian_all_data_top22$最大并发数,size=1) +
geom_text(aes(y=IP总量,label=comma(IP总量)),vjust=-1) +
geom_text(aes(y=最大并发数,label=comma(最大并发数),vjust=-1)) +
scale_y_continuous(label=NULL) +
theme_classic() +
theme(axis.ticks.y = element_blank(), axis.line.y=element_blank()) +
theme(plot.title=element_text(hjust=0.5, face="bold",size=rel(1.4))) +
labs(title="IP量与最大并发数",x=NULL)


图例 - 移除

  • guides(…=FALSE) :指定需要移除图例的标度
  • scale_fill_discrete(guide=FALSE):在对应的标度中设置为FALSE
    • scale_fill_hue() / scale_fill_discrete() / scale_fill_manual() / scale_fill_grey() / scale_fill_brewer() / scalecolor… / scale_shape_manual / scale_linetype
  • theme(legend.position=”none”):使用主题系统移除,会移除所有图例
1
2
3
4
5
6
7
8
9
10
p <- ggplot(PlantGrowth, aes(x=group, y=weight, fill=group)) + geom_boxplot()
# 移除标度fill的图例
p + guides(fill=FALSE)
# 移除标度fill的图例
p + scale_fill_discrete(guide=FALSE)
# 移除所有图例
theme(legend.position="none")


图例 - 位置

  • theme(legend.position=””) :选择不同的参数来放置图例的位置

top / bottom / left / right / none

  • theme(legend.position=c(1,1)) :确定图例的中心放置在给定坐标轴的位置

默认为c(0.5,0.5)

  • theme(legend.justification=c(1,1)) :指定图例放置在绘图区的位置


图例 - 顺序

  • 反转顺序guides(fill=guide_legend(reverse=TRUE))
  • 自定义顺序scale_fill_discrete(limits=c())将对应标度的参数limits设置为所需的顺序
1
2
3
4
p <- ggplot(PlantGrowth, aes(x=group, y=weight, fill=group)) + geom_boxplot()
# 修改项目顺序
p + scale_fill_discrete(limits=c("trt1","trt2","ctrl"))


图例 - 标题

标题 - 名称

  • labs(fill=””) :通过labs并指定对应图例的图形属性的值
    • 可同时修改不同图例对应的标题
  • scale_fill_discrete(name=””) :在设定标度时设定图例标题
1
2
3
4
5
p + labs(fill="Condition")
p + scale_fill_discrete(name="Condition")
# 同时修改不同图例对应的标题
p + labs(shape="Male/Female", color="Male/Female")


标题 - 外观

  • theme(legend.title = element_text(…)):更改图例标题的外观

标题 - 移除

  • labs(fill=NALL)
  • guides(fill = guide_legend(title=NULL))
  • scalefill…(guide=guide_legend(title=NULL))


图例 - 标签文本

标签 - 名称

  • scale_fill_discrete(labels=c(“”)) :修改图例标签的文本
    • 只修改了图例的标签,并没有修改x轴的因子水平;若修改x轴的因子水平,采用scale_x_discrete
1
2
library(gcookbook)
p + scale_fill_discrete(labels=c("Control","Treatment","Treatment 1","Treatment 2"))

标签 - 外观

  • theme(legend.text = element_text(face=””, color=””, size=14, family=””)) :修改标签的外观
  • guides(fill=guide_legend(label.theme= element_text(…)))


标签 - 多行文本

  • 标度中设置 labes 参数,使用\n 表示新行
  • grid包的unit()函数指定高度:可能出现各行文本相互叠加,通过theme()增加图例说明的高度,并减少各行的间距
1
2
3
4
5
6
p + scale_fill_discrete(labels=c("Control","Type 1\ntreatment","Type 2\ntreatment"))
# 增加图例高度并减少各行间距
library(gird)
p + scale_fill_discrete(labels=c("Control","Type 1\ntreatment","Type 2\ntreatment")) +
theme(legend.text = element_text(lineheight=0.8), legend.key.height=unit(1, "cm"))



注解

注解 - 文本

  • annotate():添加一个文类几何对象

“text”

x = , y = ; 指定添加的坐标轴位置;若坐标轴是连续型的,可以使用特殊值Inf / -Inf将其放置在区域的边缘

label = “” ;标签文字

1
p + annotate("text", x=3, y=48, label="Group 1", family="serif", fontface="italic", color="darkred", size=3, alpha=0.8)


注解 - 数学表达式

  • annotate(geom=”text”, parse=TRUE)
    • 在R的数学表达式中,不能简单把一个变量直接放在另一个变量旁而不在中间加上任何记号;若要显示两个相邻的变量,需要在中间放置一个星号*;在显示图形时,它会被当做一个不可见的乘号对待;
    • 若要显示一个可见的乘号,采用%*%
1
p + annotate("text", x=2, y=0.3, parse =TRUE, label = "frac(1,sqrt(2*pi"))*e^{-x^2/2}")"


注解 - 直线

  • geom_hline() / geom_vline() :添加横线、竖线
  • geom_abline() :添加有角度的直线
1
2
3
4
5
6
7
p <- ggplot(heightweight, aes(x=ageYear, y=heightIn, color=sex)) + geom_point()
# 添加横线和竖线
p + geom_hline(yintercept=60) + geom_vline(xintercept=14)
# 添加有角度的直线
p + geom_abline(intercept=37.4, slope=1.75)
  • 将值从数据映射到xintercept / yintercept之上,甚至是绘制另一个数据框中的值
1
2
3
library(plyr)
hw_means <- ddply(heightweight, "sex", summarise, heightIn=mean(heightIm))
p + geom_hline(aes(yintercept=heightIn, color=sex), data=hw_means, linetype = "dashed", size=1)
  • 坐标轴是离散型的,必须以数字的形式指定它们
    • 假设坐标轴表示一个因子,第一个水平为数值1,一次类推
1
2
3
4
pg <- ggplot(PlantGrowth, aes(x=group, y=weight)) + geom_point()
pw + geom_vline(xintercept = 2)
pw + geom_vline(xintercept = which(levels(PlantGrouwht$group)=="ctrl"))


注解 - 线段和箭头

  • annotate(“segment”):使用segment
  • grid包中arrow() 函数可向线段两端添加箭头和平头

angle=30(默认)

length=0.2 英寸(默认,0.508厘米)

1
2
3
library(grid)
p + annotate("segment", x=1850, xend=1820, y=-0.8, yend=-0.95, color="blue", size=2, arrow=arrow()) +
annotate("segment", x=1950, xend=1980, y=-0.25, yend=-0.25, arrow=aroow(ends="both", angel=90, length=unit(0.2,"cm")))


注解 - 矩形阴影

  • annotate(“rect”):使用rect

xmin / xmax / ymin / ymax

alpha

fill = “”

1
p + annotate("rect", xmin=1950, xmax=1980, ymin=-1, ymax=1, alpha=0.1, fill="blue")


注解 - 高亮某元素

  • 需在数据中创建一个新列,并将其映射为颜色;
  • 若仅有少量元素要高亮,可以使用原始变量并为每个水平指定颜色,而不必创建新列
1
2
3
4
5
6
7
8
9
10
pg <- PlantGrowth
pg$h1 <- "no"
pg$h1[pg$group=="trt2"] <- "yes"
ggplot(pg, aes(x=group, y=weight, fill=h1)) + geom_point() +
scale_fill_manual(values=c("grey85","#FFDDCC"), guide=FASLE)
# 根据group列设定三个水平
ggplot(PlantGrowth, aes(x=group, y=weight, fill=group)) + geom_point() +
scale_fill_manual(values=c("grey85","grey85","#FFDDCC"), guide=FASLE)


注解 - 误差线

  • geom_errorbar():添加误差线,并将变量映射到 ymin 和 ymax


注解 - 向独立分面添加注解

  • 使用分面变量创建一个新的数据框,并设定每个分面要绘制的值
  • 配合新数据框使用geom_text()
    • 若使用annotate()将在所有分面上显示
1
2
3
4
5
6
7
8
9
10
# 基本图形
p <- ggplot(mpg, aes(x=displ, y=hwy)) + geom_point() + facet_grid(.~drv)
# 存有每个分面所需标签的数据框
f_labels <- data.frame(drv=c("4","f","r"), label=c("4wd","Front","Rear"))
p + geom_text(x=6, y=40, aes(lable=label), data=f_labels)
# 如果使用annotate(),标签将在所有分面上出现
p + annotate("text", x=6, y=42, label="label text")


图形整体外观

标题

  1. labs(title=””, subtitle=””)
  2. theme(plot.title=element_text())

网格线

  1. theme(panel.grid.major = element_line() )
  2. theme(panel.grid.minor =element_line() )
  3. theme(panel.grid.major.x ) / theme(panel.grid.minor.x)

面板

  1. theme(panel.border = elment_rect() ) # 面板边界
  2. theme(panel.background = element_rect() ) # 面板背景


外观 - 图形标题

  • labs(title=””):设置图形标题
  • 将标题移动到绘图区内部 :使用一个文本注解annotate(),设定其x的位置为x值域的中间,y的位置为Inf;同时需要vjust为正值,使文本完全落入绘图区域
1
2
3
4
5
6
library(gcookbook)
p <- ggplot(heightwe)
# 移动到标题内部 ggtitle
ggplot(heightweight, aes(ageYear, heightIn)) + geom_point() +
annotate("text", x=mean(range(heightweight$ageYear)), y=Inf
, label="Age and Height\nof Schoolchildren", vjust=1.5)


外观 - 文本

  • theme(plot.title = element_text()):完成外观的设置

family :字体

face(主题元素) /fontface (文本几何对象):

color :文字颜色;颜色名称,或 “#RRGGBB”形式的十六进制颜色代码

size :字体大小;(主题元素的单位是磅,几何对象的单位是毫米)

size= rel(1.5) ,表示转为当前主题字体大小的1.5倍

hjust :横向对齐;0=左对齐;1=右对齐

0=左对齐,表示左左侧在同一垂直线;效果等同于PPT中的左对齐

vjust:纵向对齐;0=底部对齐;1=顶部对齐

0=底部对齐,表示最底端在同一水平线;效果等同PPT中的底部对齐

angle:旋转角度,单位为度

lineheight:行间距倍数


外观 - 使用主题

  • theme_bw() / theme_grey() :使用主题
    • theme_grey():灰色主题;默认
    • theme_bw() :黑白主题
    • theme_classic():白色背景,无坐标线
    • theme_minimal() :无坐标线
  • theme_get() :返回当前主题
  • theme_set(theme_bw()):设置某个主题为当前默认主题
  • theme_update() :为之后的图形设置主题
  • 使用一套现有的主题,并用theme()进行微调:theme() 必须接在指定的主题语句之后;因为ggplot根据图层的先后顺序来绘制的;
1
2
3
4
5
# 默认为灰色主题
p + theme_grey()
# 在完整的主题使用后,theme()可以正常工作
p + theme_bw() + teme(axis.title.x=element_text(color="red", size=3))


主题 - 自定义

  • 向一套现成主题添加元素的方式来创建自定义主题
  • 将图形使用修改后的主题绘图
1
2
3
4
mytheme <- theme_classic() +theme(plot.title=element_text(hjust=0.5, face="bold")) # 白色背景,无坐标线
# 使用修改后的主题
p + mytheme


外观 - 面板&网格线

  • panel.background:面板背景 - rect
  • panel.border:面板边界 - rect
  • panel.grid.major / panel.grid.minor :控制网格线 - line
  • panel.grid.major.x /y :控制横向/纵向的网格线 - line


外观 - 边界

随着边界参数值增大,绘图区与边界的距离不断增大,从而在图片上留出更多空白区域

  • plot.margin = : 依次控制 top/right/bottom/left
    • “lines”的单位距离 小于 “cm” ;即同为1,”cm”的单位大的多

= unit(c(1,1,1,1), “lines”)

= margin(1,1,1,1, “cm”)

1
2
theme(plot.margin=unit(c(1,1,1,1,),"lines"))
theme(plot.margin=margin(1,1,1,1,"cm"))


分面

分面方向取决于你希望进行比较的类型

  • 横向分布:比较各条形的高度
  • 纵向分布:比较直方图的水平分布
  • facet_grid():可以指定一个变量作为纵向子面板分割的依据,指定另一个变量为横向自面板分割的依据

colname ~ colname ;

  • facet_warp(~colname, nrow/nclo=n):默认使用相同数量的行和列

~ colname ;分面的分组变量

nrow / ncol = n ;

1
2
3
4
5
6
7
p <- ggplot(mpg, aes(x=displ, y=hwy)) + geom_point()
# 纵向排列的子面板(多行)根据drv分面
p + facet_grid(drv ~ .) # 多行一列
# 同时根据drv(纵向)和cyl(横向)分割
p + facet_grid(drv ~ cyl)


分面 - 不同坐标轴

  • free_x / free_y / free:标度设置为该值
1
p + facet_grid(drv ~ cyl, scales="free_y")


分面 - 文本标签

  • 修改因子各水平的名称
1
2
3
4
5
6
mpg2 <- within(mpg, {
drv= case_when(drv == "4" ~ "4wd",
drv == "f" ~ "Font",
drv == "r" ~ "Rear")})
ggplot(mpg2, aes(displ, hwy)) + geom_point() + facet_grid(drv~.)


分面 - 标签和标题的外观

  • strip.text:控制文本的外观
  • strip.background:控制背景的外


配色

R中的颜色-基本概念

  1. R中有3种方式表示颜色

    • 颜色名字,即上面所显示的那么多种颜色;

    • 颜色编码。每种颜色是RGB形式的,用6位16进制的字符串表示,前面加“#”号!如红色对应的RGB值为”255 0 0”,用16进制表示就是”FF0000”,在R中可以用”#FF0000”表示红色。

    • 调色板中的索引。

      R中用palette()表示调色板,默认的是颜色是下面的几种:

      >palette()

      [1] “black” “red” “green3” “blue” “cyan” “magenta” “yellow”

      [8] “gray”

      在默认情况下,col=2表示红色。这个颜色会重复利用,如指定col=10同样是红色。

  2. R预设了657种颜色。默认情况下,R中颜色的设置主要需要依靠grDevices包的支持,其中提供了大量的颜色选择函数以及生成函数,以及几种预先设置好的调色板(Palette),用以表现不同的主题。grDevices包中所有关于颜色的函数大致分为三类:固定颜色选择函数颜色生成和转换函数特定颜色主题调色板


固定颜色选择

colors() 、 palette()

  • colors()
1
2
3
4
5
6
7
8
9
# 显示657中颜色的名称
colors()
# 使用grep()来提取我们感兴趣的颜色
colors()[grep("red", colors())]
colors()[grep("sky", colors())]
# 通过设定为对象,并将其表现出现
a <- colors()[grep("sky",colors())]
palette(a)
  • palette(value):调色板
    • 这个函数用来设置调色板或者获得调色板颜色值;
    • 注意,实际上这个函数的结果可能并非“固定”颜色,但是只要设定好了调色板,它的取值就不会再改变(直到下一次重新设定调色板)
1
2
3
4
5
6
7
8
9
10
11
# 恢复调色板
palette("defalut")
# 查看默认的调色板颜色
> palette()
[1] "black" "red" "green3" "blue" "cyan" "magenta" "yellow" "gray"
# 修改调色板的值(将设定的对象传入到palette()中即可)
palette(colors()[1:10])
color <- c("red","green","blue","yellow","cyan"); palette(color)


颜色生成与转换

RGB(红绿蓝三原色混合)、HSV(色调、饱和度、纯度)、HCL(色调、色度、亮度)、灰色

  • rgb(red, green, blue, maxColorValue=1)

alpha = ;透明度;当元素图形重叠时很有用

maxColorValue =1 (默认);前三者最大的取值范围【0, maxColorValue】;通过将maxColorValue=255,可得到传统rgb颜色的16进制数值

1
2
3
4
5
> rgb(1,0,0)
[1] "#FF0000"
> rgb(255,0,0,maxColorValue = 255)
[1] "#FF0000"
  • hsv(h, s, v, gamma=1,alpha):色调(Hue)、饱和度(Saturation)、纯度(Value)来构造颜色

h, s, v 取值 [0,1]

gamma=1 ,表示伽马校正(Gamma Correction)

1
sv(h=1, s=1, v=1, gamma=1)
  • hcl(h, c, l, alpha):色调(Hue)、色度(Chroma)、亮度(Luminance)来构造颜色

h,取值[0,360];可以想象为一个角度,0-红色,120-绿色,240-蓝色;中间都是过渡色

c, l 取值[0,100],取值越大生成的颜色越亮

fixup= T/F ,表示是否修正的颜色

  • grey(level):只有一个参数levle,表示灰度水平。取值[0,1];0-纯黑;1-白色
    • level取一个向量,可生成一系列灰色之
  • rgb2hsv() / clo2rgb()


特定颜色主题调色板

  • rainbow(n, s=1, v=1, start=0, end=max(1, n-1)/n, gamma=1):彩虹的颜色(红橙黄绿青蓝紫)

n代表调色表里面有几种颜色

  • heat.colors():从红色渐变到黄色再变到白色(以体现“高温”、“白热化”
  • terrain.colors()绿色渐变到黄色再到棕色最后到白色(这些颜色适合表示地理地形)。
  • cm.colors()青色渐变到白色再到粉红色
  • topo.colors()蓝色渐变到青色再到黄色最后到棕色
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# n代表这个调色板里面有几种颜色,
# alpha介于【0,1】,反映的是透明度
rainbow(n, s = 1, v = 1, start = 0, end = max(1, n - 1)/n, alpha = 1)
heat.colors(n, alpha = 1)
terrain.colors(n, alpha = 1)
topo.colors(n, alpha = 1)
cm.colors(n, alpha = 1)
# rainbow
pie(rep(1, times = 1000), labels = "", col = rainbow(1000), border = rainbow(1000))
# heat.colors
pie(rep(1, times = 1000), labels = "", col = heat.colors(1000), border = heat.colors(1000))
# terrain.colors
pie(rep(1, times = 1000), labels = "", col = terrain.colors(1000), border = terrain.colors(1000))
# topo.colors
pie(rep(1, times = 1000), labels = "", col = topo.colors(1000), border = topo.colors(1000))
# cm.colors
pie(rep(1, times = 1000), labels = "", col = cm.colors(1000), border = cm.colors(1000))


其他参数

col 绘图使用的颜色,许多函数接受一组颜色,并对不同的数据依次使用颜色。

col.axis 坐标轴字符颜色

col.lab x,y坐标标记颜色

col.main 标题颜色

col.sub 副标题颜色

fg 绘图前景色,包括坐标轴,各类boxes

bg 绘图背景色


RColorBrewer包

颜色板被划分为序列性(sequential)离散型(diverging)、分类型(qualitative)

  • RColorBrewer::display.brewer.all()调出所有的颜色示例
  1. display.brewer.all(type = “seq”) :序列性
    • 序列型颜色板适用于从低到高排序明显的数据,浅色数字小,深色数字大。
  2. display.brewer.all(type = “div”):离散型
    • 离散型颜色板适合带“正、负”的,对极值和中间值比较注重的数据
  3. display.brewer.all(type = “qual”):分类型
    1. 分类型颜色板比较适合区分分类型的数据
  • brewer.pal(n, name):来获取该组渐变色的全部n种颜色
1
barplot(rep(1,6),col=brewer.pal(9, "YlOrRd")[3:8])


离散型

hue 来自HCL色系(Hue-Chroma-Lightness;色相-色度-亮度)

  • 亮度 [0,100],默认为65
填充色 轮廓色 描述
scale_fill_discrete() scale_color_discrete() 色轮周围均匀等距色
scale_fill_hue() scale_color_hue()
scale_fill_grey() scale_color_grey() 灰度调色板
scale_fill_brewer() scale_color_brewer() ColorBrewer调色板
scale_fill_manual() scale_color_manual() 自定义
1
2
library(gcookbook)
p <- ggplot(uspopage, aes(Year, Thousands, fill=AgeGroup)) + geom_area()


  • scale_xxx_grey():灰度调色板
    • 标度范围[0,1] (0-黑色,1-白色)
1
p + scale_fill_grey(start=0.7, end=0)


离散型 - 自定义

  • scale_xxx_manual():自定义调色板
    • 当未指定时,values 向量中的元素顺序自动匹配离散标度对应因子水平的顺序。

breaks = “”

values = “”

labels = “”

1
2
3
4
5
6
7
8
9
# 查看因子顺序的方法
levels(heightweight$sex)
## values的两种用法
# 直接指定颜色
scale_xxx_manual(values=c("red","#CC6666"))
# 指定对应的颜色
scale_xxx_manual(values=c(m="blue", f="red"))
  • 对色盲有好的颜色


连续型

填充色 轮廓色 描述
scale_fill_gradient() scale_color_gradient() 两色渐变
scale_fill_gradient2() scale_color_gradient2() 三色渐变
scale_fill_gradientn() scale_color_gradientn() 等间隔的n种颜色的渐变色


  • scale_xxx_gradient(low=””, high=””) :连续型变量的颜色

使用两者渐变色: low="black", high="white"

渐变色中间使用一种颜色划分 :low=muted("red"), mid="white", higt=muted("blue")

  • scales::muted() ,针对颜色输出一个饱和度较低的颜色

n个颜色的渐变色 :scale_color_gradient(colors=c("darkded", "orange", "yellow", "white"))


根据数值设定颜色

  1. 根据范围创建辅助列
  2. 将该列映射到填充色上
1
2
3
4
5
6
7
8
9
10
11
12
13
library(gcookbook)
cb <- subset(climate, Source=="Berkeley")
# 创建辅助列
cb$valence[cb$Anomaly10y >=0 ] <- "pos"
cb$valence[cb$Anomaly10y < 0 ] <- "neg"
# 将辅助列映射到填充标度上
ggplot(cb, aes(Year, Anomaly10y)) +
geom_area(aes(fill=valence)) +
geom_line() +
geom_hline(yintercept=0) +
scale_x_continuous(expand=c(0,0)) # 剔除两边空白的部分

上图中会发现在0水平线附近有一些凌乱的阴影。原因在于两个颜色的区域都是由各自的数据点多边形包围而成的,而这些数据点并不都在0上。

通过approx()将数据茶之道1000个点左右来解决。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> # approx()返回一个列表,包含x和y的向量
> interp <- approx(cb$Year, cb$Anomaly10y, n=1000)
> # 放在一个数据框中并重新计算valecne
> cbi <- data.frame(Year=interp$x, Anomaly10y=interp$y)
> cbi$valence[cbi$Anomaly10y >=0 ] <- "pos"
> cbi$valence[cbi$Anomaly10y < 0 ] <- "neg"
>
> # 重新作图
> ggplot(cbi, aes(Year, Anomaly10y)) +
> geom_area(aes(fill=valence), alpah=0.4) +
> geom_line() +
> geom_hline(yintercept=0) +
> scale_fill_manual(values=c("#CCEEFF","#FFDDDD"), guide=FALSE) +
> scale_x_continuous(expand=c(0,0)) # 剔除两边空白的部分
>

>