目录
Layers and overriding aesthetics
Modifying axis limits and titles
Changing the overall look with complete themes
From idea to final graphic: graphing the Rabbit data set {MASS}
原文请见R Graphics: Introduction to ggplot2 (12) (ucla.edu)https://stats.oarc.ucla.edu/stat/data/intro_ggplot2_int/ggplot2_intro_interactive.html#(12)
由于CSDN有时候图会看不见,本文将不放置图片
图形的语法元素
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对象。
ggplot(data, aes(x=xvar, y=yvar))
data: 包含要绘制的变量的data.frame的名称
x and y: 在图形上放置对象的aesthetics(视觉位置吧应该是)
xvar and yvar: 映射到x和y的数据中的变量名
注意aesthetics是在aes()中指定的,aes()本身嵌套在ggplot()中。
ggplot()内部指定的aesthetics被后续的层继承:
# scatter plot of volume vs sales
ggplot(txhousing, aes(x=volume, y=sales)) +
geom_point()
通过将Sitka数据集中的Time映射到x, size映射到y,初始化一个Time与size的关系图。
如果没有任何额外的层,就不会绘制数据。
意思就是:
ggplot(Sitka, aes(x=Time, y=size))
只有这个不会生成图,还需要像上面“+geom_point()”才会生成图,否则只会生成坐标轴。
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。
经常被使用的aesthetics:
x: 沿着x轴定位y: 沿着y轴定位
color: 对象的颜色;对于2D对象,是对象的轮廓(与下面的fill相比)
fill: 对象的填充色
linetype: 线条是如何画出来的(实线、虚线、点线等)
shape: 散点图中标记的形状
size: 对象的大小
alpha: 对象的透明度(值介于0,即transparent和1,即opaque之间——将堆叠多少个对象变成不透明的倒数)
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:
geom_bar(): 以x轴为基的bar
geom_boxplot(): boxes-and-whiskers(不知道这是什么)
geom_errorbar(): T-shaped error bars
geom_density(): 密度图
geom_histogram(): 直方图
geom_line(): lines
geom_point(): 散点图
geom_ribbon(): bands spanning y-values across a range of x-values
geom_smooth(): smoothed conditional means (e.g. loess smooth)(平滑条件均值)
geom_text(): text
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) and (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
Scales定义aesthetics值映射到数据值。
自我理解:这里的Scale理解为范围比较好。中心是aesthetics,suffix是作用的方式&功能。比如color这个aesthetic有很多类颜色,scale应该就是表示这个范围。
这里有一个color scale的例子,它定义哪些颜色映射到treat值:
color treatred ozone
blue control
想象一下,我们可能想要将颜色改为“绿色”和“橙色”。
scale_函数允许用户控制每个aesthetic的scale。这些范围函数的名称具有scale_aesthetic_suffix结构,其中aesthetic是一种aesthetic(如color、shpae或x)的名称,而suffix是一些定义范围功能的描述性词汇。
然后,为了指定scale使用的asethetic值,向scale函数的values参数(通常)提供一个值向量。
以下是一些scale函数的例子:
scale_color_manual()
: 通过手动指定每种颜色来定义任意颜色范围scale_color_hue()
: 通过指定色调范围和范围上的颜色数量来定义均匀间隔的颜色刻度scale_shape_manual()
:通过手动指定每个形状来定义任意形状比例- Function reference • ggplot2 (tidyverse.org)https://ggplot2.tidyverse.org/reference/#section-scales这个链接可以查看scale函数的更多用法
我们来看一个例子:
ggplot(diamonds, aes(x=carat, y=price, color=cut)) +
geom_point()
我们可以使用scale_colour_manual()
来指定我们想要使用的颜色:
ggplot(diamonds, aes(x=carat, y=price, color=cut)) +
geom_point() +
scale_color_manual(values=c("red", "yellow", "green", "blue", "violet"))
Scale functions for the axes
记住,x和y是aesthetics,两个轴可视化这些aesthetcis的scale。
因此,我们使用sclae函数来控制这些轴的缩放。
当y被映射到一个连续变量时,我们通常会使用scale_y_continuous()来控制它的缩放(如果y被映射到factor,则使用scale_y_discrete())。类似的函数存在于x aesthetic中。
scale_y_continuous()的一些重要参数的描述:
breaks
: 在特定数据值以及沿轴线的范围放置标记和标签labels
: 标记什么name
: 该给这个轴命名
我们当前的销量对比图y轴上的标签分别为0、5000、10000和15000
ggplot(diamonds, aes(x=carat, y=price, color=cut)) +
geom_point() +
scale_color_manual(values=c("red", "yellow", "green", "blue", "violet"))
让我们使用scale_y_continuous的break参数在y轴上的所有网格线上打上标签:
ggplot(diamonds, aes(x=carat, y=price, color=cut)) +
geom_point() +
scale_color_manual(values=c("red", "yellow", "green", "blue", "violet")) +
scale_y_continuous(breaks=c(0,2500,5000,7500,10000,12500,15000,17500))
现在让我们重新标记标记,以反映数千(美元)作为单位使用标签:
ggplot(diamonds, aes(x=carat, y=price, color=cut)) +
geom_point() +
scale_color_manual(values=c("red", "yellow", "green", "blue", "violet")) +
scale_y_continuous(breaks=c(0,2500,5000,7500,10000,12500,15000,17500),
labels=c(0,2.5,5,7.5,10,12.5,15,17.5))
最后,我们将使用name参数来重新命名y轴,以反映单位:
ggplot(diamonds, aes(x=carat, y=price, color=cut)) +
geom_point() +
scale_color_manual(values=c("red", "yellow", "green", "blue", "violet")) +
scale_y_continuous(breaks=c(0,2500,5000,7500,10000,12500,15000,17500),
labels=c(0,2.5,5,7.5,10,12.5,15,17.5),
name="price(thousands of dollars)")
> ggplot(diamonds, aes(x=carat, y=price,color=cut))+
+ geom_point()+
+ scale_color_manual(values=c('red', 'yellow', 'green', 'blue', 'violet'))+
+ scale_y_continuous(breaks=c(0,2500,5000,7500,10000,12500,15000,17500),labels=c(0,2.5,5,7.5,10,12.5,15,17.5),name="price(thousands of dollars)")+
+ scale_x_continuous(breaks=c(150,180,210,240),labels=c(5,6,7,8),name="time(months)")
Modifying axis limits and titles
虽然我们可以使用scale_x_continuous()这样的scale函数来控制x轴的限制和标题,但我们也可以使用以下快捷函数:
lims()
,xlim()
,ylim()
: 设置轴的限制xlab()
,ylab()
,ggtitle()
,labs()
: 给x轴、y轴或图形赋予标签(标题);labs()可以为所有的aesthetic和标题设置标签
ggplot(diamonds, aes(x=carat, y=price, color=cut)) +
geom_point() +
xlim(c(1,3)) # cut ranges from 0 to 5 in the data
我们可以使用labs()为整个图形、轴和图例(参考线)指定一个整体标题。
ggplot(diamonds, aes(x=carat, y=price, color=cut)) +
geom_point() +
labs(x="CARAT", y="PRICE", color="CUT", title="CARAT vs PRICE by CUT")
Guides visualize scales
Guides(轴和标记)将刻scale(刻度)可视化,显示数据值及其匹配的aesthetics。x轴是一个guide,它将数据值的映射可视化到沿着x轴的位置。一个color scale 的guide(图例)显示了哪些颜色映射到哪些数据值。
默认情况下显示大多数guides。guides()函数为每个比例设置和删除参考线。
这里我们使用guides()来移除color scale的标记(比如什么值对应什么颜色)
# notice no legend on the right anymore
ggplot(txhousing, aes(x=volume, y=sales, color=median)) +
geom_point() +
guides(color="none")
这里的作用是把颜色即其标记去掉。
Coordinate systems
坐标系定义了物体在空间上的位置。大多数图都是用笛卡尔坐标系绘制的,这堂课上的所有图也是如此。然而,ggplot2提供了多种坐标系统,包括极坐标系、翻转的Carteisan(笛卡尔)坐标系和地图投影。
Faceting (paneling)
使用faceting函数facet_wrap()和facet_grid()将图分割成小的多个(面板)。结果图显示了每个图如何沿面变量(faceting variables)变化。
facet_wrap()将多个图形包装到多行图形面板中。在facet_wrap()内部,指定~,那么用+来分隔变量(比如cut变量中有5中类型,原来是放在一个图里面,现在放在分别放在多个图里面)。行数和列数可以用参数nrow和ncol指定。
ggplot(diamonds, aes(x=carat, y=price)) +
geom_point() +
facet_wrap(~cut) # create a ribbon of plots using cut
facet_grid()允许直接指定哪些变量用于沿着行和列分割数据/图。将行分隔变量放在~之前,列分隔变量放在后面。符号 . 表示无指定。
ggplot(diamonds, aes(x=carat, y=price)) +
geom_point() +
facet_grid(clarity~cut) # split using clarity along rows along columns using cut
> ggplot(Sitka, aes(x=Time, y=size))+
+ geom_point()+
+ facet_grid(.~treat)
Themes
Themes控制与数据无关的图形元素。例如:
- background color(背景色)
- size of fonts(字体大小)
- gridlines(网格线)
- color of labels(标签颜色)
要修改这些,我们使用theme()函数,它有大量称为theme elements的参数,这些参数控制图的各种非数据元素。
一些theme()参数的例子,以及它们控制的图形的哪些方面:
axis.line
: lines forming x-axis and y-axisaxis.line.x
: just the line for x-axislegend.position
: positioning of the legend on the graphpanel.background
: the background of the graphpanel.border
: the border around the graphtitle:
all titles on the graph关于theme elements的全面介绍请见:
Modify components of a theme — theme • ggplot2 (tidyverse.org)https://ggplot2.tidyverse.org/reference/theme.html
Specifying theme()
arguments
图中的大多数非数据元素可以被归类为直线(例如轴线、tick marks)、矩形(例如背景)或文本(例如轴线标题、tick labels)。每个类别都有一个相关联的element_函数来指定控制其外观的参数:
element_line()
- can specifycolor
,size
,linetype
, etc.element_rect()
- can specifyfill
,color
,size
, etc.element_text()
- can specifyfamily
,face
,size
,color
,angle
, etc.element_blank()
- removes theme elements from graph
在theme()内部,我们使用适当的element_函数来控制主题元素的属性。
例如,x轴和y轴是线,它们都由theme()的参数axis.Line,因此它们的可视化属性,如color和size(thickness),被指定为element_line()的参数:
ggplot(txhousing, aes(x=volume, y=sales, color=median)) +
geom_point() +
theme(axis.line=element_line(color="black", size=2)) # size in mm
另一方面,图形的背景,由theme()参数面板控制。Background是一个矩形,所以fill color和border color等参数可以被element_rect()指定。
ggplot(txhousing, aes(x=volume, y=sales, color=median)) +
geom_point() +
theme(axis.line=element_line(color="black", size=2),
panel.background=element_rect(fill="white", color="gray")) # color is the border color
通过element_text(),我们可以控制文本元素(比如font family或face(“bold”,“italic”,“bold.italic”))的属性,比如title,它控制两个轴的标题。
ggplot(txhousing, aes(x=volume, y=sales, color=median)) +
geom_point() +
theme(axis.line=element_line(color="black", size=2),
panel.background=element_rect(fill="white", color="gray"),
title=element_text(family="serif", face="bold"))
注意:“sans”,“serif”和“mono”是ggplot2在不需要下载额外的R包的情况下唯一可用的字体系列。有关更多信息,请见:
RPubs - tidbitR - Changing Font family in ggplothttps://rpubs.com/vprabhuram/222833
最后,一些theme()参数不使用element_函数来控制它们的属性,比如legend.position,它只接受值“none”、“left”、“right”、“bottom”和“top”。
ggplot(txhousing, aes(x=volume, y=sales, color=median)) +
geom_point() +
theme(axis.line=element_line(color="black", size=2),
panel.background=element_rect(fill="white", color="gray"),
title=element_text(family="serif", face="bold"),
legend.position="bottom")
然后,我们可以在theme()中使用legend.text=element.text()来旋转图例标签(此处不展示)。
当使用theme()时记得使用这个网址。
> ggplot(Sitka, aes(x=Time, y=size))+
+ geom_point()+
+ theme(axis.ticks=element_line(color="white"))
Changing the overall look with complete themes
ggplot2包提供了几个完整的主题,这些主题对图形的整体背景外观进行了一些更改(参见此处获取完整的描述)。
一些例子:
theme_bw()
theme_light()
theme_dark()
theme_classic()
主题通常会调整背景的颜色和组成图形非数据部分的大多数线条的颜色。
theme_classic()模仿了基R图形的外观(应该就是保持原样吧):
ggplot(txhousing, aes(x=volume, y=sales, color=median)) +
geom_point() +
theme_classic()
Theme_dark()在外观上做了一个巨大的改变:
ggplot(txhousing, aes(x=volume, y=sales, color=median)) +
geom_point() +
theme_dark()
Saving plots to files
ggsave()使保存图变得容易。默认情况下,最后显示的图形会被保存,但是我们也可以将图形保存到R对象中。
ggsave尝试从文件扩展名中猜测用来保存图像的设备,因此使用有意义的扩展名。可用的设备包括eps/ps, tex (pictex),pdf, jpeg, tiff, png, bmp, svg和wmf。
ggsave()其他的重要参数:
width
height
units
:units
ofwidth
andheight
of plot file ("in"
,"cm"
or"mm"
)dpi
: plot resolution in dots per inch以每英寸点为单位的绘图分辨率plot
: name of object with stored plot
#save last displayed plot as pdf
ggsave("plot.pdf")
#if you're working with lots of graphs, you can store them in R objects
p <- ggplot(Sitka, aes(x=Time, y=size)) +
geom_point()
#You can then use the plot argument of ggsave() to specify which plot to save instead of the last
ggsave("myplot.png", plot=p)
From idea to final graphic: graphing the Rabbit
data set {MASS
}
为了练习使用图形语法的元素,我们将从我们想要显示的内容的想法开始,一步一步地,我们将添加和调整图形,直到我们觉得它可以与观众分享。
在下一个图中,我们将可视化Rabbit数据集中的数据,它也是由MASS包加载的。
> library(ggplot2)
> library(MASS)
> data(Rabbit)
> str(Rabbit)
Rabbit数据集描述了一个实验,其中:
5只兔分别用生理盐水(对照组)和血清素受体拮抗剂(阻断剂)“MDL 72222”治疗。
在注射治疗药物或对照药物后,每只家兔注射6次递增剂量的苯双胍,使血压随剂量升高。
测量血压的变化作为结果。
每只家兔测血压12次,治疗组和对照组各测6次
目的是测试血压的变化是否依赖于血清素受体的激活。
数据集包含以下5个变量的60行(5只兔子测量12次):
BPchange:相对于实验开始时的血压变化
dose:苯基双胍的剂量(单位:微克)
Run: trial的标签
Treatment:对照组或MDL
Animal:动物ID(“R1”至“R5”)
The idea of the graph
在药物研究中,我们想要创建一个剂量-反应曲线。在这项研究中,我们想了解在生理盐水(对照)和血清素拮抗剂MDL 7222(治疗)存在的情况下,血压变化与苯双胍(一种血压升高药物)的剂量是如何相关的。
需要考虑的问题:
在对照组和治疗药物下,每只兔子都被测量了6次(不同剂量的血压兴奋剂)。我们如何区分这两种情况下的剂量反应曲线?
我们只研究了5只动物(在给予对照和治疗药物后,每只注射6剂量的苯基双胍),所以我们可以将所有单个兔子的曲线拟合在一张图上
所以,我们想要一个代表每只兔子的剂量-反应曲线的图表,最好是每只兔子的治疗和控制条件的单独曲线。
让我们一步一步地构建这个图。
Rabbit graph 1
什么geom会需要到画出计量—反应曲线?
geom_line()
需要的aesthetic是什么?
x与y
Rabbit graph 2
ggplot(Rabbit, aes(x=Dose, y=BPchange)) +
geom_line()
这显然不是我们想要的——这个图将数据视为所有数据都属于一条线上。我们想要通过兔子(可变动物)分开的线。我们如何指定它呢?
将Animal映射到一个组aesthetics,如group,color,linetype.
让我们想象一下,我们被限制在生成一个无色的图形,因此我们不能使用color。我们将代替使用linetype来分隔Animal。
Rabbit graph 3
ggplot(Rabbit, aes(x=Dose, y=BPchange, linetype=Animal)) +
geom_line()
这看起来还是不对吗?为什么?
记住,每只兔子在每个剂量下都进行了两次测试,一次是在MDL 7222治疗药物的存在下,一次是在对照组药物的存在下。每个动物的两条分开的曲线仍然被连接成一条。
因此,我们需要将每个动物的治疗曲线与对照曲线分开。我们怎样才能做到呢?
一种方法是将Treatment分配给像color一样的分组aesthetics。
ggplot(Rabbit, aes(x=Dose, y=BPchange, color=Treatment, linetype=Animal)) +
geom_line()
然而,我们把自己限制在无色的图形上。你能想到其他方法来分离曲线吗?
用Faceting
Rabbit graph 4
ggplot(Rabbit, aes(x=Dose, y=BPchange, linetype=Animal)) +
geom_line() +
facet_wrap(~Treatment)
现在我们终于开始看到我们想要的图形了!
仅仅根据linetype来区分线条可能有点困难。让我们向图形中添加一些点,但通过Treatment改变点的形状。
如何向随形状变化的图形添加点?
geom_point()将shape映射到Animal
Rabbit graph 5
ggplot(Rabbit, aes(x=Dose, y=BPchange, linetype=Animal, shape=Animal)) +
geom_line() +
facet_wrap(~Treatment) +
geom_point()
取得良好进展!
现在,假设我们想要选择绘制的形状,而不是使用默认值。我们需要什么函数(或什么类型的函数)来改变形状?
一个scale函数!具体来说,scale_shape_manual()。这些形状是用0到25之间的整数代码指定的。查看帮助页面的Points(?dot或?pch)来查看代码和形状的表格。
Rabbit graph 6
ggplot(Rabbit, aes(x=Dose, y=BPchange, shape=Animal, linetype=Animal)) +
geom_line() +
facet_wrap(~Treatment) +
geom_point() +
scale_shape_manual(values=c(0, 3, 8, 16, 17))
好的!现在我们已经完成了向图中添加数据的工作。现在我们继续进行一些微调。
首先,让我们改变x轴和y轴的标题。什么函数可以改变这两个?
lab()
Rabbit graph 7
ggplot(Rabbit, aes(x=Dose, y=BPchange, shape=Animal, linetype=Animal)) +
geom_point() +
geom_line() +
facet_wrap(~Treatment) +
scale_shape_manual(values=c(0, 3, 8, 16, 17)) +
labs(x="Dose(mcg)", y="Change in blood pressure")
差不多了!
假设我们不喜欢灰色背景和白色网格线,而是想使用白色背景和灰色网格线。
我们将使用什么功能来调整这些元素?
theme()
控制图形背景的theme()参数是panel.background。我们应该使用哪个element_函数来指定panel.background的参数?
element_rect()
theme()参数panel.grid控制网格线。我们应该使用哪个element_函数来指定网格线的参数?
element_line()
Rabbit graph 8
ggplot(Rabbit, aes(x=Dose, y=BPchange, shape=Animal, linetype=Animal)) +
geom_point() +
geom_line() +
facet_wrap(~Treatment) +
scale_shape_manual(values=c(0, 3, 8, 16, 17)) +
labs(x="Dose(mcg)", y="Change in blood pressure") +
theme(panel.background = element_rect(fill="white"),
panel.grid=element_line(color="gray90"))
最后一个步骤!
现在我们想要使用theme()来调整轴、legend和面板标题(“Control”和“MDL”)以使用粗体。
我们将使用的theme参数是title和strip.text。我们应该使用哪个element_函数来指定这些参数?
element_text()
我们将在element_text中使用face参数将标题设置为“粗体”。
Rabbit graph finished
ggplot(Rabbit, aes(x=Dose, y=BPchange, shape=Animal, linetype=Animal)) +
geom_point() +
geom_line() +
facet_wrap(~Treatment) +
scale_shape_manual(values=c(0, 3, 8, 16, 17)) +
labs(x="Dose(mcg)", y="Change in blood pressure") +
theme(panel.background = element_rect(fill="white"),
panel.grid=element_line(color="gray90"),
title=element_text(face="bold"),
strip.text=element_text(face="bold"))
Advice for working with ggplot2
New dataset birthwt
{MASS
}
birthwt数据集包含与低出生体重相关的危险因素的数据。
数据由10个变量的189个观测值组成,均为数值:
low
: 0/1 indicator of birth weight < 2.5 kgage
: mother’s agelwt
: mother’s weight in poundsrace
: mother’s race, (1=white, 2=black, 3=other)smoke
: 0/1 indicator of smoking during pregnancyptl
: number of previous premature labors(早产次数)ht
: 0/1 indicator of history of hypertension(高血压)ui
: 0/1 indicator of uterine irritability(子宫刺激性)ftv
: number of physician visits during first trimester(前三个月)bwt
: birth weight
让我们先看看birthwt数据集的结构,以了解如何测量变量。
> data(birthwt)
> str(birthwt)
Aesthetics, numeric and factor (categorical) variables
数据集中的变量通常可以分为数值变量(numeric variables)(数值是表示数量的有意义的表示)和因子(分类)变量(factor (categorical) variables)(数值通常是表示类别而不是数量的成员关系的代码)。
In R
, we can encode variables as “factors” with the factor()
function.
一些aesthetics可以映射到数值或分类变量,并且将以不同的方式scaled。
包括:
x
andy
: continuous or discrete axescolor
andfill
: 颜色梯度scales或均匀间隔的色调scalesOther aesthetics can only be mapped to categorical variables:
shape
linetype
And finally some aethetics should only be mapped to numeric variables (a warning is issued if mapped to a categorical variable):
size
alpha
Aesthetic scales are formed differently for numeric and factor variables
让我们看看当使用birthwt数据集(其中所有的变量最初都是数值型的)映射到不同类型的变量时,aesthetic是如何表现的。
当color被映射到一个数值变量时,将使用一个颜色梯度scale:
ggplot(birthwt, aes(x=age, y=bwt, color=race)) +
geom_point()
注意:尽管我们只是使用race作为数值变量来演示ggplot如何处理它,但我们不建议将分类变量作为数值变量对待。
当将颜色映射到一个因子变量时,将使用均匀间隔的色调的颜色刻度。我们可以使用factor()将数字变量转换为aes()中的因子:
ggplot(birthwt, aes(x=age, y=bwt, color=factor(race))) +
geom_point()
如果我们试图将shape映射到race的数值版本,就会出现错误,因为shape只接受因子变量。
Shape接受race的因子表示:
ggplot(birthwt, aes(x=age, y=bwt, shape=factor(race))) +
geom_point()
最后,像alpha和size这样的aesthetic应该只用于真正的数值变量,如果变量是一个因子,则会发出警告:
ggplot(birthwt, aes(x=age, y=bwt, size=factor(race))) +
geom_point()
## Warning: Using size for a discrete variable is not advised.
Convert categorical variables to factors before graphing
我们建议在绘图之前将所有分类变量转换为因子,原因如下:
- 我们不需要在每次创建图形时都将变量包含在factor()中
- We can label the levels to use in all graphs
ggplot2
will discourage mapping a factor variable to an inappropriate aesthetic likesize
> ggplot(birthwt, aes(x=age, y=bwt, shape=smoke, alpha=ui))+
+ geom_point()
Overlapping data points in scatter plots
当两个数据点在图上有相同的值时,它们通常会占据相同的位置,导致其中一个遮盖了另一个。
在这个例子中,我们将race(一个factor变量)映射到x,将年龄(以年为单位)映射到y:
ggplot(birthwt, aes(x=race, y=age)) +
geom_point()
数据集中有189个数据点,但远远少于图中可见的189个点,因为很多点是完全重叠的。
为了解决这个问题,我们有一个“位置调整”的选择,它可以在geom函数的position参数中指定。
对于geom_point(),我们尝试用两个中的一个:
position="jitter"
: add a little random noise to positionposition="identity"
: overlay points (覆盖点)(the default forgeom_point()
)
通过在之前的散点图中添加position="jitter",我们可以更好地看到在每个年龄阶段有多少个点:
ggplot(birthwt, aes(x=race, y=age)) +
geom_point(position="jitter")