install.packages("tidyverse")
library(tidyverse)
mpg
?mpg
#创建ggplot图形
##将 displ 放在 x 轴,hwy 放在 y 轴
ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy))
#引擎大小(displ)和燃油效率(hwy)之间是负相关关系
#创建了一个坐标系,你可以在 它上面添加图层。
ggplot()
#ggplot()的第一个参数是要在图中使用的数据集。
ggplot(data = mpg)
#添加一个或多个图层就可以完成这张图
#函数geom_point()向图中添加一个点层,这样就可以创建一张散点图
#ggplot2 中包含了多种几何对象函数,每种函数都可以向图中添加不同类型的图层。
#ggplot2 中的每个几何对象函数都有一个 mapping参数
#定义了如何将数据集中的 变量映射为图形属性。
#mapping 参数总是与 aes() 函数成对出现,
#aes() 函数的 x 参数和y 参数分别指定了映射到 x 轴的变量与映射到 y 轴的变量。
#要想生成一张图,将以ggplot2 会自动为每个变量值分配唯一的图形属性水平(本例中是唯一的颜色),这个过程 称为标度变换。下代码中的尖括号部分替换为数据集、几何对象函数或映射集合即可
#ggplot(data = ) +
#从
#图形属性:图形属性是图中对象的可视化属性,其中包括数据点的大小、形状和颜色。
#通过将第三个变量映射为图形属性,可以向二维散点图中添加第三个变量
#将点的颜色映射为变量 class,从而揭示每辆汽车的类型:
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, color = class))
#要想将图形属性映射为变量,需要在函数 aes() 中将图形属性名称和变量名称关联起来。
#ggplot2 会自动为每个变量值分配唯一的图形属性水平(本例中是唯一的颜色),这个过程 称为标度变换。
#ggplot2 还会添加一个图例,以表示图形属性水平和变量值之间的对应关系。
#也可以用同样的方式将其映射为点的大小。在下面的示例中,每个点的实际大小表示其所属的类别。
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, size = class))
#> Warning: Using size for a discrete variable is not advised.
#将无序变量(class)映射为有序图形属性(size)可不是好主意。
#可以将 class 映射为控制数据点透明度的 alpha 图形属性。
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, alpha = class))
#还可以将其映射为点的形状。
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, shape = class))
#ggplot2 只能同时使用 6 种形状。默认情况下,当使用这种图形属性时,
#多出的变量值将不会出现在图中。
#数据点的 x 轴位置和 y 轴位置本身就是图形属性,即可以映射为变量来表示数据信息的可视化属性。
#对你所使用的每个图形属性来说,函数 aes() 都可以将其名称与一个待显示变量关联起来。
#aes() 将图层中使用的每个图形属性映射集合在一起,然后传递给该图层的映射参数。
#一旦映射了图形属性,ggplot2 会处理好其余的事情。它会为图形属性选择一个合适的标 度,
#并创建图例来表示图形属性水平和变量值之间的映射关系。
#ggplot2 不会为 x 和 y 这两 个图形属性创建图例,而会创建带有刻度标记和标签的坐标轴。
#坐标轴就相当于图例,可以体现出位置和变量值之间的映射关系。
#还可以手动为几何对象设置图形属性。例如,我们可以让图中的所有点都为蓝色:
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy), color = "blue")
#此时颜色不会传达关于变量的信息,只是改变图的外观。
#要想手动设置图形属性,需要按名称进行设置,将其作为几何对象函数的一个参数。
#这也就是说,需要在函数 aes() 的外部进行设置。
#此外,还需要为这个图形属性选择一个有意义的值。
#颜色名称是一个字符串。
#点的大小用毫米表示。
#点的形状是一个数值,color 和 fill 这两个图形属性。
#空心形状(0~14)的边界颜色由 color 决定;
#实心形状(15~20)的填充颜色由 color 决定;
#填充形状(21~24)的边界 颜色由 color 决定,填充颜色由 fill 决定。
## + 必须放在一行代码的末尾,而不是开头。
# ggplot(data = mpg)
# + geom_point(mapping = aes(x = displ, y = hwy))
#添加额外变量的一种方法是使用图形属性。
#另一种方法是将图分割成多个分面,即可以显示数据子集的子图。
#这种方法特别适合添加分类变量。
#要想通过单个变量对图进行分面,可以使用函数 facet_wrap()。
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
facet_wrap(~ class, nrow = 2)
#在 ~ 符号后面加一个变量名,传递给 facet_wrap() 的变量应该是离散型的。
#要想通过两个变量对图进行分面,需要在绘图命令中加入函数 facet_grid()。
#第一个参数也是一个公式,但该公式包含由 ~ 隔开的两个变量名。
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
facet_grid(drv ~ cyl)
#如果不想在行或列的维度进行分面,你可以使用.来代替变量名,例如+ facet_grid(. ~ cyl)
#在使用函数 facet_grid() 时,一般应该将具有更多唯一值的变量放在列上。
#ggplot2 中的每个几何对象函数都有一个 mapping 参数。但是,不是每种图形属性都适合每种几何对象。
#geom_smooth() 函数可以按照不同的线型绘制出不同的曲线,
#每条曲线对应映射到线型的变量的一个唯一值
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy, linetype = drv))
#?geom_smooth
#http://rstudio.com/cheatsheets
#扩展包甚至提供了更多(可以在 https://www.ggplot2exts.org 查看更多样例)
#只要将一个图形属性映射为一个离散变量(如上个示例中的 linetype),
# ggplot2 就会自动对数据进行分组来绘制多个几何对象。
#按照图形属性的这种分组不用添加图例,也不用为几何对象添加区分特征
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy))
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy, group = drv))
ggplot(data = mpg) +
geom_smooth(
mapping = aes(x = displ, y = hwy, color = drv),
show.legend = FALSE )
#要想在同一张图中显示多个几何对象,可以向 ggplot() 函数中添加多个几何对象函数:
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
geom_smooth(mapping = aes(x = displ, y = hwy))
#但是,这样代码就产生了一些重复。
#避免这种重复的方法是将一组映射传递给 ggplot() 函数。
#ggplot2 会将这些映射作为全局映射应用到图中的每个几何对象中。
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point() +
geom_smooth()
#如果将映射放在几何对象函数中,那么 ggplot2 会将其看作这个图层的局部映射
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point(mapping = aes(color = class)) +
geom_smooth()
#你也可以为不同的图层指定不同的数据。
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point(mapping = aes(color = class)) +
geom_smooth(
data = filter(mpg, class == "subcompact"),
se = FALSE )
#图中的平滑曲线表示的只是 mpg 数据集的一个子集,即微型车。
#geom_smooth() 函数中的局部数据参数覆盖了 ggplot() 函数中的全局数据参数,
#当然仅对这个图层有效
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut))
#条形图 x 轴显示的是 cut,这是 diamonds 数据集中的一个变量。
#y 轴显示的是 count,但 count 不是 diamonds 中的变量!
#很多图形绘制的是数据集的原始 数据,比如散点图。
#另外一些图形则可以绘制那些计算出的新数据,比如条形图。
#条形图、直方图和频率多边形图可以对数据进行分箱,
#然后绘制出分箱数量和落在每个 分箱的数据点的数量。
#平滑曲线会为数据拟合一个模型,然后绘制出模型预测值。
#箱线图可以计算出数据分布的多种摘要统计量,并显示一个特殊形式的箱体。
#绘图时用来计算新数据的算法称为 stat(statistical transformation,统计变换)
#?geom_bar 显示出 stat 的默认值是 count
#通常来说,几何对象函数和统计变换函数可以互换使用。
#你可以使用 stat_count() 替换 geom_bar() 来重新生成前面那张图:
ggplot(data = diamonds) +
stat_count(mapping = aes(x = cut))
#每个几何对象函数都有一个默认统计变换,每个统计变换函数都有一个默认几何对象。
#ggplot2中柱状图有geom_bar与geom_col两种形式,
#前者默认是绘制频数(样本量),后者才是我们实际使用的数据映射成柱子高度。
#geom_bar()是单一变量。
#geom_bar如果绘制实际数据映射,需要添加**stat=“identity”**统计变换
ggplot(data = diamonds) +
geom_col(mapping = aes(x = cut,y=color))
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut,y=color),stat = "identity")
#覆盖从统计变换生成的变量到图形属性的默认映射。
#显示一 张表示比例(而不是计数)的条形
ggplot(data = diamonds) +
geom_bar(
mapping = aes(x = cut, y = ..prop.., group = 1)
)
#如果想要找出由统计变换计算出的变量,可以查看帮助文件中的“Computed variables” 一节。
#group=1
#因为纵轴是..prop..,即分类变量中每个类别占总量的比,
#group=1就是将这些类别当作一组的这样一个整体去分别计算各个类别的占比,所以须有group=1。
#否则,默认的就是各个类别各自一个“组”,
#在计数时就是普通的条形图,而在计算占比时就成了“各自为政”——每个类别都是百分百占比,
#所以每个条形图都是顶头的一样高。
#在代码中强调统计变换。
#可以使用 stat_summary() 函数将人们的注意力吸引到你计算出的那些摘要统计量上。
#stat_summary() 函数为 x 的每个唯一值计算 y 值的摘要统计
ggplot(data = diamonds) +
stat_summary(
mapping = aes(x = cut, y = depth),
fun.ymin = min,
fun.ymax = max,
fun.y = median
)
#stat_summary的默认几何图形是geom_pointrange
#条形图还有一项神奇的功能,你可以使用 color 或者 fill(这个更有用)图形属性来为条形图上色
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, color = cut))
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, fill = cut))
#如果将 fill 图形属性映射到另一个变量(如 clarity),那么条形会自动分块堆叠起来。
#每个彩色矩形表示 cut 和 clarity 的一种组合。
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, fill = clarity))
#这种堆叠是由 position 参数设定的位置调整功能自动完成的。
#如果不想生成堆叠式条形图,你还可以使用以下 3 种选项之一:"identity"、"fill" 和 "dodge"。
#position = "identity"将每个对象直接显示在图中。
#这种方式不太适合条形图,因为条形会彼此重叠。
#为了让重叠部分能够显示出来,
#我们可以设置 alpha 参数为一个较小的数,从而使得条形略微透明;
#或者设定 fill = NA,让条形完全透明:
ggplot(
data = diamonds,
mapping = aes(x = cut, fill = clarity)
)+
geom_bar(alpha = 1/5, position = "identity")
ggplot(
data = diamonds,
mapping = aes(x = cut, color = clarity)
)+
geom_bar(fill = NA, position = "identity")
#position = "fill"的效果与堆叠相似,但每组堆叠条形具有同样的高度,
#因此这种条形图可以非常轻松地比较各组间的比例
ggplot(data = diamonds) +
geom_bar(
mapping = aes(x = cut, fill = clarity),
position = "fill"
)
#position = "dodge"将每组中的条形依次并列放置,
#这样可以非常轻松地比较每个条形表示的具体数值
ggplot(data = diamonds) +
geom_bar(
mapping = aes(x = cut, fill = clarity),
position = "dodge"
)
#此外还有一种位置调整,虽然不适合条形图,但非常适合散点图。
#一些点显示在一个网格上时,很多点彼此重叠了。这个问题称为过绘制。
#position = "jitter"为每 个数据点添加一个很小的随机扰动,这样就可以将重叠的点分散开来,
#因为不可能有两个点会收到同样的随机扰动
ggplot(data = mpg) +
geom_point(
mapping = aes(x = displ, y = hwy),
position = "jitter"
)
# ggplot2 提供了 geom_ point(position = "jitter") 的一种快速实现方式:geom_jitter()
#geom_jitter()对点添加随机扰动
ggplot(data = mpg, mapping = aes(x = cty, y = hwy)) +
geom_jitter()
#geom_count()重复的点越多,点越大
ggplot(data = mpg, mapping = aes(x = cty, y = hwy)) +
geom_count()
ggplot(mpg, aes(class, hwy))+geom_boxplot()
ggplot(mpg, aes(class, hwy))+stat_boxplot()
#默认的坐标系是笛卡儿直角坐标系
#coord_flip() 函数可以交换 x 轴和 y 轴。
#当想要绘制水平箱线图时,这非常有用。
ggplot(data = mpg, mapping = aes(x = class, y = hwy)) +
geom_boxplot()
ggplot(data = mpg, mapping = aes(x = class, y = hwy)) +
geom_boxplot() +
coord_flip()
#它也非常适合使用长标签,但要想在 x 轴上不重叠地安排好它们是非常困难的
#coord_quickmap() 函数可以为地图设置合适的纵横比。
#当使用 ggplot2 绘制空间数据时, 这个函数特别重要(遗憾的是本书不涉及空间数据)
nz <- map_data("nz")
ggplot(nz, aes(long, lat, group = group)) +
geom_polygon(fill = "white", color = "black")
ggplot(nz, aes(long, lat, group = group)) +
geom_polygon(fill = "white", color = "black") +
coord_quickmap()
#coord_polar() 函数使用极坐标系。
#极坐标系可以揭示出条形图和鸡冠花图间的一种有趣联系:
bar <- ggplot(data = diamonds) +
geom_bar(
mapping = aes(x = cut, fill = cut), show.legend = FALSE,
width = 1
)+
theme(aspect.ratio = 1) + labs(x = NULL, y = NULL)
bar + coord_flip()
bar + coord_polar()
#width = 1把柱形图中间的空去掉
#使用 coord_polar() 函数将堆叠式条形图转换为饼图。
bar <- ggplot(data = diamonds) +geom_bar(
mapping = aes(x = cut, fill = cut), show.legend = FALSE,
width = 1, position = "fill"
)+
theme(aspect.ratio = 1) + labs(x = NULL, y = NULL)
bar + coord_polar()
#theta = "y"是将角度按y轴变量来设置,如不设置,会出现中间空心原点
bar <- ggplot(data = diamonds) +geom_bar(
mapping = aes(x = cut, fill = cut), show.legend = FALSE,
width = 1, position = "fill"
)+
theme(aspect.ratio = 1) + labs(x = NULL, y = NULL)
bar + coord_polar(theta = "y")
#多组的bar图也能画出饼图
bar <- ggplot(data = diamonds) +geom_bar(
mapping = aes(x = cut, fill = color), show.legend = FALSE,
width = 1, position = "fill"
)+
theme(aspect.ratio = 1) + labs(x = NULL, y = NULL)
bar + coord_polar(theta = "y")
#lab()函数可以给图层增加x和y的标签和title
bar <- ggplot(data = diamonds) +geom_bar(
mapping = aes(x = cut, fill = cut), show.legend = FALSE,
width = 1, position = "fill"
)+
theme(aspect.ratio = 1) + labs(x = NULL, y = NULL)
bar + coord_polar()+
labs(y = "Highway MPG", x = "", title = "Highway MPG by car class")
#coord_fixed()保持线为45度
ggplot(data = mpg, mapping = aes(x = cty, y = hwy)) +
geom_point() +
geom_abline() +
coord_fixed()
#图形分层语法
#ggplot(data = ) +
#
# mapping = aes(
# stat =
# position =
# )+
#任何图形精确地描述为数据集、几何对象、映射集合、统计变换、
#位置调整、坐标系和分面模式的一个组合,
#图形语法正是基于这样的深刻理解构建出来的。