原文请见R Graphics: Introduction to ggplot2 (12) (ucla.edu)
https://stats.oarc.ucla.edu/stat/data/intro_ggplot2_int/ggplot2_intro_interactive.html#(12)
图形的语法元素
1. Data:变量,可映射到图的美学特征。
2. Geoms:图形上的对象/形状。
3. Stats: 汇总数据的统计转换(例如 mean,confidence intervals(置信区间))
4. Scales: 图形值(aesthetic values)到数据值的映射。图例和轴可视化尺度
5. Coordinate systems(坐标系):数据被映射到图形上的平面。
6. Faceting: 将数据分成子集,以创建同一图形的多个变体(分面)。
Sitka数据集(这一部分其实就是一个示范而已)
为了练习使用图形语法,我们将使用Sitka数据集(来自MASS包)。
注意:用包加载到R中的数据集可以立即使用。要在RStudio的Environment窗格中看到对象(所以你可以点击查看它),在数据集上运行data(),然后在数据集上运行另一个函数,如str()。
> library(ggplot2)
> library(MASS)
> data()
> str(Sitka)
# 出现
'data.frame': 395 obs. of 4 variables:
$ size : num 4.51 4.98 5.41 5.9 6.15 4.24 4.2 4.68 4.92 4.96 ...
$ Time : num 152 174 201 227 258 152 174 201 227 258 ...
$ tree : int 1 1 1 1 1 2 2 2 2 2 ...
$ treat: Factor w/ 2 levels "control","ozone": 2 2 2 2 2 2 2 2 2 2 ...
ggplot()函数与aesthetics
所有图形都以指定ggplot()函数开始(注意:不是包名ggplot2)
在ggplot()函数中,我们指定包含变量的数据集。这些变量将映射到aesthetics(图的视觉属性)。数据集必须是一个data.frame对象。
注意aesthetics是在aes()中指定的,aes()本身嵌套在ggplot()中。
gplot()内部指定的aesthetics被后续的层继承:
# scatter plot of volume vs sales
ggplot(txhousing, aes(x=volume, y=sales)) +
geom_point()
通过将Sitka数据集中的Time映射到x, size映射到y,初始化一个Time与size的关系图。
如果没有任何额外的层,就不会绘制数据。
Layers and overriding aesthetics
单独指定x和y的aesthetics将产生一个只有两个轴的图。
ggplot(data = txhousing, aes(x=volume, y=sales))
我们将带有字符+的图层添加到图形中,以添加图形组件。
图层由geoms,stats,scales和themes组成,我们将详细讨论这些内容。
请记住,每个后续层都从ggplot()继承其aesthetics。但是,在一个层中指定新的aesthetics将覆盖ggplot()中指定的aesthetics。
# scatter plot of volume vs sales
# with rug plot colored by median sale price
ggplot(txhousing, aes(x=volume, y=sales)) + # x=volume and y=sales inherited by all layers
geom_point() +
geom_rug(aes(color=median)) # color will only apply to the rug plot because not specified in ggplot()
> library(ggplot2)
> library(MASS)
> ggplot(Sitka, aes(x=Time, y=size))+
+ geom_point(aes(color=treat))+
+ geom_smooth()
上面两个例子其实就是只要前面有加号就会后面的操作就会继承ggplot()的aesthetics,就是在ggplot()所建立的坐标轴上继续。注意:此处coloring仅应用于geom_point().
Aesthetics
aesthetcis是图形中对象的视觉属性。
哪些aesthetics是需要的,哪些aesthetics是允许的,这取决于geom。
Mapping vs setting
Map是在aes()函数内将aesthetics对应到变量。
# mapping color to median inside of aes()
ggplot(txhousing, aes(x=volume, y=sales)) +
geom_point(aes(color=median))
Set是在aes()函数外将aesthetics对应到常量。
# setting color to green outside of aes()
ggplot(txhousing, aes(x=volume, y=sales)) +
geom_point(color="green")
若果是在aes()函数内将aesthetics对应到常量会有意料之外的结果。
# color="green" inside of aes()
# geom_point() cannot find a variable called "green" and
# uses a default color instead
ggplot(txhousing, aes(x=volume, y=sales)) +
geom_point(aes(color="green"))
# 虽为color但是可能为其它颜色
Geoms
Geom函数在plot时产生的几何形状上有所不同。
Geoms and aesthetics
每个Geom需要aesthetics提供来定义。例如,geom_point()同时需要x和y,这是散点图的最小规范。
Geoms接受aesthetics中的arguments而不同。例如:geom_point()接受aesthetic shape,但是geom_bar()不接受shape。
查看geom函数的帮助文件,可了解所需并理解asethetics。在geom的帮助文件的Asethetics部分中,所要求asethetics是加粗的。
我们来看看常见的geoms.
Histograms
ggplot(txhousing, aes(x=median)) +
geom_histogram()
直方图是描述连续变量分布的常用选择。
> ggplot(Sitka, aes(x=size))+
+ geom_histogram(bins=20)
bins默认为30,且bins不是aesthetic,所以不应该在aes()内。
Density plots
ggplot(txhousing, aes(x=median)) +
geom_density()
密度图基本上是平滑的直方图。
密度图与直方图不同,可以通过将分组变量映射到color来分组单独绘制。
ggplot(txhousing, aes(x=median, color=factor(month))) +
geom_density()
Boxplots
ggplot(txhousing, aes(x=factor(year), y=median)) +
geom_boxplot()
箱线图可以直观地显示分布的特定统计信息:
- lower and upper hinges of box: first and third quartiles
- middle line: median
- lower and upper whiskers: (hinge−1.5×IQR)(hinge−1.5×IQR) and (hinge+1.5×IQR)(hinge+1.5×IQR) where IQR is the interquartile range (distance between hinges)
- dots: outliers
箱形图对于比较组间连续变量的整体分布可能特别有用。
> ggplot(Sitka, aes(x=size, y=treat))+
+ geom_boxplot()
Bar plots
ggplot(diamonds, aes(x=cut)) +
geom_bar()
条形图常用于显示factor(categorical)变量的频率。
> ggplot(Sitka, aes(x=treat))+
+ geom_bar()
填充条状图的颜色不是由aesthetic颜色控制的,而是由fill控制的,它只能映射到一个factor(catgorical)变量。我们可以通过将其中一个变量映射到geom_bar()中来可视化变量的交叉表:
ggplot(diamonds, aes(x=cut, fill=clarity)) +
geom_bar()
> ggplot(Sitka, aes(x=treat, fill=factor(Time)))+
+ geom_bar()
Scatter plots
# scatter of volume vs sales
ggplot(txhousing, aes(x=volume, y=sales)) +
geom_point()
散点图描述了成对变量(通常都是连续的)之间的协变。
geom_point()描述了映射到x和y的变量之间的协变。
散点图是最灵活的图之一,因为变量可以映射到许多aesthetic上,如color、shape、size和alpha。
ggplot(txhousing, aes(x=volume, y=sales,
color=median, alpha=listings, size=inventory)) +
geom_point()
Line graphs
ggplot(txhousing, aes(x=date, y=sales, group=city)) +
geom_line()
线形图用线而不是点来描述映射到x和y的变量之间的协变。
geom_line()将把所有数据视为属于一行,除非一个变量被映射到以下aestetics之一,将数据分组为单独的行:
group
: lines will look the samecolor
: line colors will vary with mapped variablelinetype
: line patterns will vary with mapped variable
让我们首先检查一个没有分组的线形图:
ggplot(txhousing, aes(x=date, y=sales)) +
geom_line()
如您所见,除非数据表示单个系列,否则线形图通常需要进行一些分组。
在geom_line()中使用color或linetype将隐式地对行进行分组。
ggplot(txhousing, aes(x=date, y=sales, color=city)) +
geom_line()
让我们试着为每棵树画出单独的线(生长曲线)
> ggplot(Sitka, aes(x=Time, y=size, group=tree))+
+ geom_line()
> ggplot(Sitka, aes(x=Time, y=size, group=tree, color=treat))+
+ geom_line()
> ggplot(Sitka, aes(x=Time, y=size, group=tree, linetype=treat))+
+ geom_line()
*Stats*
stat函数对数据进行统计转换,通常是某种形式的汇总,如平均值、标准差或置信区间。
每个stat函数都与一个默认的geom相关联,所以提供(render)形状并不需要geom。
stat_summary()可能是所有stat函数中最有用的一个,它应用一个summary函数,将x变量的每个值映射到y的变量。默认的汇总函数是mean_se(),以及相关的geom geom_pointrange(),它将为x变量的每个值生成一个映射到y的变量的平均值(点)和标准误差(线)的图。
# summarize sales (y) for each year (x)
ggplot(txhousing, aes(x=year, y=sales)) +
stat_summary()
> ggplot(Sitka, aes(x=Time, y=size))+
+ stat_summary()
stat_summary()的强大之处在于,您可以使用任何接受向量作为summary函数的函数(例如mean()、var()、max()等),并且还可以更改geom来调整绘制的形状。
Scales
未完待续