用 ggplot2 绘制柱状图的笔记

您所在的位置:网站首页 均值柱状图怎么看 用 ggplot2 绘制柱状图的笔记

用 ggplot2 绘制柱状图的笔记

2024-07-03 08:39| 来源: 网络整理| 查看: 265

由于俺会用的 R 绘图包只有 echarts4r,此包语法简洁、高效易用,用来做数据的可视化展示时够用,但用来做探索性数据分析稍有不足,且 echarts4r 不支持 crosstalk,暂无法完成图表数据共享,所以还需要再学习一个作图系统达成互补。备选项有二:plotly 和 ggplot2。考虑到 ggplot2 可以用plotly::ggplotly()转换成 plotly 图形,且网络上介绍它的文章和书籍更多,可绘制的图形种类也更丰富,所以尽管此包官方文档相当厚实,也先学了再说。后面还是不够用的话,再学别的。

一般来说,图形可展现数据的占比、大小、趋势、结构、层次、分配、归类、变化、流动等特点。鉴于 ggplot2 以及各类 gg 包子们能够绘制的图形类型繁多,俺决定从基础的柱状图开始学起。由于俺现在对 ggplot2 不够熟悉,因此笔记力求细致,若有错漏之处,猴年马月再改。

本篇笔记所用的 ggplot2 版本是3.4.2。

一、ggplot2 基础概念 🔗

使用 ggplot2 绘图需要三个最基本的元素:数据集、几何对象、图形属性映射。数据集自不必再说,没有数据就无法绘图。几何对象就是将数据展示到坐标系上的几何图形对象,比如折线图就是直线几何对象,条形图就是条形几何对象,散点图就是点几何对象。在一个二维坐标系上,最基础的几何图形就是点和线,线又可以分成直线、曲线,多条线合起来组成了面,也就有了更加丰富的几何图形如矩形、圆形、多边形等。但只有数据和几何图形是不够的,还需要有更多的图形属性使图形展现的信息更加清晰、简洁,比如将多组数据绘制成散点图时,无法区分哪些点属于哪个组别,那么可以对不同组别的点映射不同的形状、颜色、透明度、大小来加以区分。

ggplot2 功能十分强大,可调整的图形细节也十分丰富,整个图形语法系统可以扩展出如下几个方面:数据集(DATA)、几何对象(GEOM_FUNCTION)、图形属性映射(mapping = aes())、统计变换(statistic transformation)、位置调整(position)、坐标系(coordinate)、分面(facet)、标度(scale)、主题(theme)。其中,标度(scale)即视觉映射,用于将数据映射到几何对象的颜色、形状、大小等图形属性。在图形属性映射(mapping = aes())里面也可以指定颜色、形状等属性,但是在标度(scale)里面指定的视觉映射更具特色,前者指定更统一的属性,后者指定更加差异化的属性,比如渐变颜色等。

ggplot(data = ) + ( mapping = aes(), stat = , position = ) + + + +

ggplot2 有别于其他绘图包的最大特点是图层,关于图层这个概念,有几点需要梳理清楚。

其一,每一个几何对象都是一个图层,对应地,每个绘制几何对象的函数如 GEOM_FUNCTION()都会创建一个图层,都有一个mapping = aes(),这是设置图形属性映射的函数。

其二,除了 ggplot()图层,各 GEOM_FUNCTION()图层中的图形属性映射仅对本图层起作用。绘制一个最基本的 ggplot2 图形至少需要两个图层,一个 ggplot()和一个 GEOM_FUNCTION(),通常由前者引入数据集,由后者指定绘制的具体几何图形,比如绘制柱状图就是 geom_bar(),绘制散点图就是 geom_point()。需要注意的是,ggplot()图层里面的映射属于全局映射,而 GEOM_FUNCTION()图层里面的映射属于局部映射,但 GEOM_FUNCTION()图层的映射优先级更高且设定内容只对本图层起作用。因此,当 ggplot()和 GEOM_FUNCTION()都设定了同一种图形属性的不同内容时,后者的设定会覆盖前者;而当某种图形属性在 ggplot()中有设定而在 GEOM_FUNCTION()中没有设定时,后者缺失的部分会直接引用前者设定的内容。

其三,除了绘制几何对象的函数,其他函数也可以修改图层中的图形属性,其优先级依+号后面的函数编写顺序而定。

1.1.图形属性映射(Aes) 🔗

在每个几何对象函数中,有两个有关图形属性映射的大类,一是轴的映射,比如在直角坐标系下指定 x、y 轴需映射的变量;二是美学映射,根据 ggplot2 的美学规范(Aesthetic specifications),又可细分为如下几类。

颜色

colour/color1:颜色或边框颜色,可以填写一个代表颜色的字符串如"red",或 RGB 值如"#44A57CFF",或者填写一个数据集中的变量名称,默认按此变量分组映射不同的颜色。

fill:填充颜色,填入一个变量名称时,同样默认按此变量分别映射不同的填充颜色。填入一个字符串时,字符串的内容也是图例项的名称。

shape:形状。填入一个变量名称时,默认按此变量分别映射不同的形状,但 ggplot2只能同时使用6种形状,第7个或更多类别的形状将不会出现在图形中。也可填入单个字符,以此作为点的形状展示。或者填入代表形状的英文单词,如 circle、square、diamond、triangle 等。或填入0-24之间的整数数字,分别代表不同的形状,相同形状由 color 和 fill 参数来区分,比如空心形状(0-14)的边界颜色由 color 设定,实心形状(15-20)的填充颜色由 color 设定,填充形状(21-24)的边界颜色由 color 设定、填充颜色由 fill 设定。

size:大小,可以填入数字,单位是毫米,或者填入一个变量名称,需注意这是一个有序图形属性。

alpha:透明度,可以填0-1之间的数值,或者填入一个变量名称,这同样是一个有序图形属性。

线

linetype:线型,填数字或字符串(0 = "blank", 1 = "solid", 2 = "dashed", 3 = "dotted", 4 = "dotdash", 5 = "longdash", 6 = "twodash"),分别对应空白、实线、虚线、点线、点划线、长虚线、点划线。

linewidth:线宽,填数字。

lineend:线末端的形状,填字符串,圆形(round), butt,方形(square),默认为 butt。

linejoin:折线的连接处的形状,填字符串,圆形(round)、斜角(mitre)、斜面(bevel),默认为圆形(round)。

文字

字体(Font Family):参数名称是 family,默认字体是 sans,也可以填 serif、mono 等。

字型(Font face):参数名称是 fontface,是字体粗细、倾斜的结合体,比如 italic 表示倾斜,而 bold.italic 表示加粗倾斜。

字号(Font size):比如 size = 12/.pt 表示字号为12。

对齐方式(Justification):分为水平参数 hjust 和垂直参数 vjust,取值范围可以是0-1之间的数值,或者 top、middle、bottom、left、center、right 中的一个字符串。

分组

group:分组,自动为分类变量的每个类别绘制一个独立的几何对象。可以填任意常数,代表不分组。或者填入一个变量名称来指定分组变量。 1.2.几何图形(Geoms) 🔗

在 ggplot2 中,所有的几何图形以及基本的点、线元素都是一个 GEOM_FUNCTION()函数。与 echarts4r 的语法相比,两者对图形类别划分的粗细不同,但也有很多相似之处。又由于平时绘图翻 echarts4r 入门和 echarts 配置项手册比较多,俺决定整理一个 echarts4r 与 ggplot2 的对照表,尽早作出区分,免得学习前期不同语法在脑子里打架。

ggplot2 类别 图形名称 ggplot2 函数 对照 echarts4r 函数 图形基础元素 空白矩形单元格 geom_blank() graphic - 曲线 geom_curve() ? - 路径 geom_path() ? - 多边形 geom_polygon() e_polygon_g() - 矩形 geom_rect() e_rect_g()/e_mark_area() - 带状图形 geom_ribbon() e_band() 单变量(连续型) 基础折线图 geom_line() e_line() - 面积图 geom_area() e_area() - 阶梯折线图 geom_step(direction = "hv") e_step() - 密度曲线图 geom_density(kernel = "gaussian") e_density() - 点图 geom_dotplot() ? - 频数图? geom_freqpoly() ? - 直方图 geom_histogram() e_histogram() - QQ图 geom_qq() ? 单变量(离散型) 柱状图/条形图 geom_bar() e_bar() - 饼图 ? e_pie() 双变量(两个连续型) 标签图? geom_label()/geom_text() ? - 散点图 geom_point() e_scatter() - 分位数图 geom_quantile() ? - 地毯图? geom_rug(sides = “bl") ? - 回归线 geom_smooth(method = lm) e_lm() 双变量(离散型&连续型) 柱状图 geom_col() e_bar() - 箱线图 geom_boxplot() e_boxplot() - 点图 geom_dotplot(binaxis = "y", stackdir = “center") ? - 提琴图 geom_violin(scale = “area") ? 双变量(两个离散型) 棋盘图 geom_count() ? - ? geom_jitter() ? 双变量(连续二元分布) ? geom_bin2d() ? - ? geom_density_2d() ? - ? geom_hex() ? 三变量 轮廓图 geom_contour() ? - ? geom_contour_filled() ? - ? geom_raeter() ? - ? geom_tile() ? 其他 雷达图 ? e_radar() - 热力图 ? e_heatmap() - 关系图 ? Graph - 树图 ? e_tree() - 矩形树图 ? e_treemap() - 旭日图 ? e_sunburst() - 平行坐标 ? e_aprallel() - 桑基图 ? e_sankey() - 漏斗图 ? e_funnel() - 仪表盘 ? e_gauge() - 日历图 ? e_calendar() - 词云 ? e_cloud() - 三维立体图 ? 3D 1.3.坐标系(Coordinate) 🔗

ggplot2 本身适用于绘制静态图形,在坐标系种类的数量上比适用于绘制交互图形的 echarts4r 略少。整理完上一小节后,俺心里纳闷为撒没有一个geom_pie之类的函数用来绘制饼图呢?整理了坐标系后才明白,原来 ggplot2 的一切绘图基础都是基于坐标系,默认的直角坐标系是没法绘制饼图的,需要转换成极坐标系才能做到。

坐标系名称 ggplot2 函数 echarts4r 函数 直角坐标系 coord_cartesian() e_grid() (固定xy轴比例) coord_fixed() ? (交换xy轴) ggplot(,aes(y=))/coord_flip() e_flip_coords() (缩放xy轴) coord_trans() ? 极坐标系 coord_polar() e_polar() (角度轴) coord_polar(theta = "x") e_angle_axis() (径向轴) coord_polar(theta = "y") e_radius_axis() 地理坐标系 coord_map() e_map() 单轴坐标系 ? e_single_axis() 日历坐标系 ? e_calendar() 平行坐标系 ? e_parallel() 二、柱状图 🔗

绘图数据选用 ggplot2 包自带的 diamonds 数据集,一共有53940条数据,10个变量。

price:石头价格,单位是美元,范围是326–18823。

carat:石头重量,范围是0.2–5.01。

cut:切割质量,有序变量,分五个等级(Fair, Good, Very Good, Premium, Ideal)。

color:石头颜色,有序变量,也分多个等级,D (最好) - J (最差)。

clarity:石头匀净度,有序变量(I1 (最差), SI2, SI1, VS2, VS1, VVS2, VVS1, IF (最好))。

x:石头长度,单位是毫米,范围是0–10.74。

y:石头宽度,单位是毫米,范围是0–58.9。

z:石头高度,单位是毫米,范围是0–31.8。

depth:衡量石头的一个指标,计算公式是 z / mean(x, y) = 2 * z / (x + y),范围是43–79。

table:衡量石头的一个指标,范围是43–95。

使用 echarts4r 绘图时,要求数据是已经整理好的。diamonds 数据集本身是拥有10个变量的清单数据,如果要对 cut(切割质量)各类别汇总计数后展示为柱状图,需要先对数据做一番处理。使用 ggplot2 对已经汇总处理好的数据绘制柱状图,可以用 geom_col()函数,或者 geom_bar(stat = 'identity')指定对原始数据绘图。

library(ggplot2) library(data.table) library(echarts4r) # data(package = "ggplot2") # help("diamonds") # str(diamonds) data(diamonds) diamonds.new # 指定横轴 # e_bar(freq) # 指定纵轴 # 用 ggplot2 绘图,指定数据集、x 轴、y 轴 ggplot(data = diamonds.new1) + geom_col(mapping = aes(x = cut, y = freq)) # 使用原始数据绘图,效果同上 # ggplot(data = diamonds.new1) + geom_bar(mapping = aes(x = cut, y = freq), stat = 'identity')

如果总是先处理数据再绘图,那么就浪费了 ggplot2 的强大特点,ggplot2 在数据处理环节可通过指定统计方法来完成,可以直接根据清单数据绘图,此时绘制柱状图的函数是geom_bar(),指定stat = 'count'表示对 cut 列的各项类别先汇总统计频数,然后用频数绘制柱状图。

# 基础柱状图,指定 x 轴 ggplot(data = diamonds) + geom_bar(mapping = aes(x = cut), stat = 'count') # 基础柱状图,指定 y 轴 ggplot(data = diamonds) + geom_bar(mapping = aes(y = cut), stat = 'count') 2.1.不同坐标系 🔗 coord_cartesian():直角坐标系。

一般情况下,柱状图是默认在笛卡尔坐标系(直角坐标系)上绘图,加上 coord_cartesian()函数后可设置 xlim、ylim 参数来限制 x 轴、y 轴的取值范围。需要注意的是 coord_cartesian(ylim = c(0, 25000))等同于 ylim(0, 25000)。

ggplot(data = diamonds) + geom_bar(mapping = aes(x = cut), stat = 'count') + coord_cartesian(ylim = c(0, 25000)) coord_flip():x、y 轴互换。

当在直角坐标系上横轴和纵轴互换时,柱状图变成条形图,可以使用 coord_flip()函数达到此效果,或者干脆把轴属性的映射关系由 aes(x = cut)换成 aes(y = cut)。

ggplot(data = diamonds) + geom_bar(mapping = aes(x = cut), stat = 'count') + coord_flip() coord_polar():极坐标系。 theta:指定把x轴还是y轴卷起来。 start:起始角度。 direction:1表示顺时针,-1表示逆时针。 # 极坐标系下,默认把 x 轴卷起来 ggplot(data = diamonds) + geom_bar(mapping = aes(x = cut), stat = 'count') + coord_polar(theta = "x") # 极坐标系下,指定把 y 轴卷起来 ggplot(data = diamonds) + geom_bar(mapping = aes(x = cut), stat = 'count') + coord_polar(theta = "y") 2.2.填充柱子颜色 🔗

若要填充柱子颜色,需指定 fill 参数。如果指定 x 轴变量和填充变量相同,那么会给每个柱子填上不同颜色,此时的填充颜色来源于默认主题。而如果指定 x 轴变量和填充变量相同,那么会产生分组堆叠效果,见后文第2.3小节。

ggplot(data = diamonds) + geom_bar(mapping = aes(x = cut, fill = cut), stat = 'count')

也可引入调色盘来填充柱子颜色,如下需要用 scale_fill_brewer()函数。。

# 将 ggplot2 升级到3.4.2后,与吉卜力相关的配色函数被删除了 # ggplot(data = diamonds) + geom_bar(mapping = aes(x = cut, fill = cut), stat = 'count') + scale_fill_ghibli_d(name = "MarnieMedium2") # 查看调色盘名称 `RColorBrewer::display.brewer.all()` ggplot(data = diamonds) + geom_bar(mapping = aes(x = cut, fill = cut), stat = 'count') + scale_fill_brewer(palette = "PiyG")

还可以手动指定填充的颜色,如下需要用 scale_fill_manual()函数。

ggplot(data = diamonds) + geom_bar(mapping = aes(x = cut, fill = cut), stat = 'count') + scale_fill_manual(values = c('black', 'black', 'red', 'black', 'black'))

指定 color 参数可以改变柱子边框颜色,这点令俺超级意外,此前从未想过居然还可以这么做。

ggplot(data = diamonds) + geom_bar(mapping = aes(x = cut, color='red'), stat = 'count') 2.3.分组 🔗

当绘图时指定的 x 轴变量为离散型变量时,默认对 x 轴变量分组展示。在下面的例子中不再统计频数,而是用after_stat(prop)来计算每个组别占整体的比例,如果按照默认分组,会得到每个组别占每个组别的整体比例都是100%,但此时希望得到每个 x 轴变量的组别占全部数据的比例,需要设置 group 参数为任意常数,即不再按照默认分组计算比例。

ggplot(data = diamonds) + geom_bar(mapping = aes(x = cut, y = after_stat(prop), group = 1))

也可以直接指定分组变量,指定不同的分组变量将会得到不同的输出结果。

d


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3