ggplot2是R语言中最优雅,最美观的图形框架。它具有精心设计的结构。本教程重点介绍可用于制作任何ggplot的基础结构。但是,在ggplot2中绘制图的方式与学习曲线陡峭的基本图形截然不同。因此,将您对基本图形的了解留在后面并继续。
首先,您需要告诉ggplot使用什么数据集data。这是使用ggplot(df)函数完成的,其中df的数据框包含制作绘图所需的所有功能。这是最基本的步骤。与基础图形不同,ggplot不会将向量作为参数。
您可以aes()通过指定数据集中的各个变量,将想要应用到ggplot(内部参数)的任何美学效果添加到其中-例如X和Y轴。颜色,大小,形状应基于其更改的变量也可以在此处本身指定。此处指定的美学将被您随后添加的所有geom层继承。
如果以后打算添加更多的图层(可能是折线图顶部的条形图),则可以在添加这些图层时指定各自的外观。
下面,我展示了一些如何在自身diamonds随附的数据集中使用ggplot的示例ggplot2。但是,在添加几何图层之前,不会打印任何图。
library(ggplot2)
ggplot(diamonds) # if only the dataset is known.
ggplot(diamonds, aes(x=carat)) # if only X-axis is known. The Y-axis can be specified in respective geoms.
ggplot(diamonds, aes(x=carat, y=price)) # if both X and Y axes are fixed for all layers.
ggplot(diamonds, aes(x=carat, color=cut)) # Each category of the 'cut' variable will now have a distinct color, once a geom is added.
该aes论点代表美学。ggplot2还将图的X轴和Y轴以及颜色,大小,形状,填充等也视为美观。如果要固定颜色,大小等(即,不根据数据框中的变量而变化) ,您需要aes()像这样在之外指定它。
ggplot(diamonds, aes(x=carat), color="steelblue")
ggplot2中的图层也称为“geoms”。完成基本设置后,您可以将几何图形一个附加在另一个图形之上。该文档提供了所有可用几何的完整列表。
library(tidyverse)
## -- Attaching packages ------------------------ tidyverse 1.3.0 --
## √ tibble 2.1.3 √ dplyr 0.8.3
## √ tidyr 1.0.0 √ stringr 1.4.0
## √ readr 1.3.1 √ forcats 0.4.0
## √ purrr 0.3.3
## -- Conflicts --------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
library(DT)
ggplot(diamonds, aes(x = carat, y = price, color = cut)) +
geom_point() +
geom_smooth() # Adding scatterplot geom (layer1) and smoothing geom (layer2).
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
我们在该绘图中添加了两个图层(geom)-geom_point()和geom_smooth()。由于X轴Y轴和颜色是在ggplot()设置本身中定义的,因此这两层继承了那些美学。另外,您也可以在geom层中指定这些外观。
ggplot(diamonds) +
geom_point(aes(x=carat, y=price, color=cut)) +
geom_smooth(aes(x=carat, y=price, color=cut),se = F) # Same as above but specifying the aesthetics inside the geoms.
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
注意X和Y轴以及点的颜色如何根据cut变量的值而变化。图例已自动添加。我想提出一个改变。我不想在每个级别上使用多条平滑线,而是将它们全部集成在一条线下。怎么做?color从geom_smooth()层次上消除美学将达到目的。
ggplot(diamonds) +
geom_point(aes(x=carat, y=price, color=cut)) +
geom_smooth(aes(x=carat, y=price)) # Remove color from geom_smooth
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
ggplot(diamonds, aes(x=carat, y=price)) +
geom_point(aes(color=cut)) +
geom_smooth() # same but simpler
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
这对您来说是一个快速的挑战。能否使点的形状随color功能而变化?
尽管设置过程花费了我们很多代码,但增加了更多的复杂性,例如层,每个cut的不同颜色等都很容易。想象一下,如果要在基本图形中进行编写,将必须编写多少代码?感谢ggplot2!
diamonds %>%
ggplot(aes(carat,price)) +
geom_point(aes(color = cut,shape = cut),size = 2) +
geom_smooth(aes(color = cut,linetype = cut),se = FALSE,size = 1.5)
## Warning: Using shapes for an ordinal variable is not advised
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
现在,您已经绘制了图形的主要部分。您可能想要添加图解的主标题,并可能更改X和Y轴标题。这可以通过labs用于指定标签的层来完成。但是,操纵标签的大小,颜色是“主题”的工作。
library(ggplot2)
gg <- ggplot(diamonds, aes(x=carat, y=price, color=cut)) +
geom_point() +
labs(title="Scatterplot", x="Carat", y="Price") # add axis lables and plot title.
print(gg)
将添加该图的主标题,并且将X和Y轴标签大写。
注意:如果要在函数内部显示ggplot,则需要显式保存它,然后使用进行打印print(gg),就像我们上面所做的那样。
除了我们要增加标签的大小并更改图例标题外,几乎所有内容都已设置。调整标签的大小可以用做theme()通过设置功能plot.title,axis.text.x和axis.text.y。需要在中指定它们element_text()。如果要删除其中任何一个,请将其设置为element_blank(),它将完全消失。
调整图例标题有些棘手。如果您的图例是某个color属性的图例,并且根据因数而变化,则您需要设置scale_color_discrete(),其中颜色部分属于color属性,而离散部分属于离散值,因为图例是基于因数变量的。
gg1 <- gg + theme(plot.title=element_text(size=25, face="bold",hjust = 0.5),
axis.text.x=element_text(size=10), # X轴
axis.text.y=element_text(size=10),
axis.title.x=element_text(size=15), # X标题
axis.title.y=element_text(size=15)) +
scale_color_discrete(name="Cut of diamonds") # add title and axis text, change legend title.
print(gg1) # print the plot
如果图例显示基于因子变量的形状属性,则需要使用进行更改scale_shape_discrete(name="legend title")。如果它是一个连续变量,请scale_shape_continuous(name="legend title")改用。
所以现在,如果您的图例基于fill连续变量的属性,您能猜出要使用的函数吗?
答案是scale_fill_continuous(name="legend title")。
在上一张图表中,您在同一张图表中具有所有不同cut绘制值的散点图。如果您想要一张图表一张cut呢?
gg1
gg1 +
facet_wrap(~cut,nrow = 5) +
theme(legend.position = "bottom")
gg1 +
facet_wrap(~cut,ncol = 3)
facet_wrap(formula)接受一个公式作为参数。RHS上的项目对应于该列。LHS上的项目定义行。
gg1 + facet_wrap(color ~ cut) # row: color, column: cut
在中facet_wrap,X和Y轴的比例固定为默认容纳所有点。这将使属性的比较有意义,因为它们的规模相同。但是,可以通过设置参数使比例尺自由漫游,使图表看起来分布更均匀scales=free。
gg1 + facet_wrap(color ~ cut, scales="free") # row: color, column: cut
为了进行比较,您也可以使用将所有图解放在一个网格中facet_grid(formula)。
gg1 + facet_grid(color ~ cut,scales = "free") # In a grid # 相当于四个变量
请注意,各个图的标题已消失,为绘图区域留出更多空间。
该ggfortify软件包使直接从时间序列对象中绘制时间序列非常容易,而不必将其转换为数据框。下面的示例AirPassengers一步一步地绘制时间序列。
library(ggfortify)
library(forecast)
## Registered S3 method overwritten by 'xts':
## method from
## as.zoo.xts zoo
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
## Registered S3 methods overwritten by 'forecast':
## method from
## autoplot.Arima ggfortify
## autoplot.acf ggfortify
## autoplot.ar ggfortify
## autoplot.bats ggfortify
## autoplot.decomposed.ts ggfortify
## autoplot.ets ggfortify
## autoplot.forecast ggfortify
## autoplot.stl ggfortify
## autoplot.ts ggfortify
## fitted.ar ggfortify
## fitted.fracdiff fracdiff
## fortify.ts ggfortify
## residuals.ar ggfortify
## residuals.fracdiff fracdiff
autoplot(AirPassengers) +
labs(title="AirPassengers")+ # where AirPassengers is a 'ts' object
theme(plot.title = element_text(hjust = 0.5))
绘制多个时间序列要求您具有数据帧格式的数据,其中一列是将用于X轴的日期。
方法1:转换后,您只需要继续在一个之上叠加多个时间序列。
方法2:通过tidyr将设置id为日期字段来融化数据框。然后只需添加一个geom_line并将颜色美感设置为variable(过程中创建)即可。
# Approach 1:
data(economics, package="ggplot2") # init data
economics %>% head()
## # A tibble: 6 x 6
## date pce pop psavert uempmed unemploy
## <date> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1967-07-01 507. 198712 12.6 4.5 2944
## 2 1967-08-01 510. 198911 12.6 4.7 2945
## 3 1967-09-01 516. 199113 11.9 4.6 2958
## 4 1967-10-01 512. 199311 12.9 4.9 3143
## 5 1967-11-01 517. 199498 12.8 4.7 3066
## 6 1967-12-01 525. 199657 11.8 4.8 3018
ggplot(economics) +
geom_line(aes(x=date, y=pce, color="pcs")) +
geom_line(aes(x=date, y=unemploy, color="unemploy")) +
scale_color_discrete(name="Legend") +
labs(title="Economics") + # plot multiple time series using 'geom_line's
theme(axis.text.x = element_text(size = 10),
axis.text.y = element_text(size = 10),
axis.title = element_text(size = 15)) +
theme(plot.title = element_text(hjust = 0.5,size = 25))
economics %>%
select(date,pce,unemploy) %>%
tidyr::gather(key = id,value = value,-date) %>%
ggplot(aes(date,value,color = id)) +
geom_line() +
scale_color_discrete("Color")
ggplot2的缺点是不可能在同一图上获得多个Y轴。以相同的比例绘制多个时间序列会使序列中的几个看起来很小。一个替代方法是facet_wrap设置它scales='free'。
economics %>%
select("date", "pce", "unemploy", "psavert") %>%
tidyr::gather(key = id,value = value,-date) %>%
ggplot() +
geom_line(aes(x=date, y=value, color=id)) +
facet_wrap( ~ id, scales="free")
economics %>%
ggplot() +
geom_point(aes(date,pce),col = "red") + xlab(label = NULL)-> p1
economics %>%
ggplot() +
geom_line(aes(date,unemploy),col = 'blue') + xlab(label = NULL) -> p2
economics %>%
ggplot() +
geom_line(aes(date,psavert),color = 'green') -> p3
gridExtra::grid.arrange(p1,p2,p3,nrow = 3)
默认情况下,ggplot会制作一个“计数”条形图,这意味着它会计算x美学指定的项目的频率并将其绘制出来。使用这种格式,您无需指定Y美学。但是,如果您要制作Y美学给出的绝对数的条形图,则需要geom_bar在内进行设置stat="identity"。
plot1 <-
ggplot(mtcars, aes(x = cyl)) +
geom_bar() +
labs(title = "Frequency bar chart") + # Y axis derived from counts of X item
theme(plot.title = element_text(hjust = 0.5)) +
theme(plot.title = element_text(size = 20),
axis.text = element_text(size = 10),
axis.title = element_text(size = 15))
print(plot1)
df <- data.frame(var=c("a", "b", "c"), nums=c(1:3))
plot2 <- ggplot(df, aes(x=var, y=nums)) +
geom_bar(stat = "identity") + # Y axis is explicit. 'stat=identity'
theme(plot.title = element_text(size = 20),
axis.text = element_text(size = 10),
axis.title = element_text(size = 15)) +
theme(plot.title = element_text(hjust = 0.5)) +
labs(title = "BarChart")
print(plot2)
该gridExtra软件包提供了在单个网格中配置多个ggplots的功能。
library(gridExtra)
##
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
##
## combine
grid.arrange(plot1, plot2, ncol=2)
df <- data.frame(var=c("a", "b", "c"),
nums=c(1:3))
df
## var nums
## 1 a 1
## 2 b 2
## 3 c 3
ggplot(df, aes(x=var, y=nums)) +
geom_bar(stat = "identity") +
coord_flip() +
labs(title="Coordinates are flipped") +
theme(plot.title = element_text(hjust = 0.5))
有3种方法可以更改X和Y轴限制。
coord_cartesian(xlim = c(x1,x2))xlim(c(x1,x2))scale_x_continuous(limits = c(x1,x2))警告:第 2项和第3项将从数据本身中删除超出限制的数据点。因此,如果添加任何平滑线等,结果将失真。项1(coord_cartesian)不会删除任何数据点,而是会放大到图表的特定区域。
ggplot(diamonds,aes(x = carat, y = price, color = cut)) +
geom_point() +
geom_smooth() +
coord_cartesian(ylim = c(0, 10000)) +
labs(title = "Coord_cartesian zoomed in!") +
theme(plot.title = element_text(hjust = 0.5))
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
ggplot(diamonds, aes(x=carat, y=price, color=cut)) +
geom_point() +
geom_smooth() +
ylim(c(0, 10000)) +
labs(title="Data points deleted: Note the change in smoothing lines!") +
theme(plot.title = element_text(hjust = 0.5))
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
## Warning: Removed 5222 rows containing non-finite values (stat_smooth).
## Warning: Removed 5222 rows containing missing values (geom_point).
#> Warning messages:
#> 1: Removed 5222 rows containing non-finite values
#> (stat_smooth).
#> 2: Removed 5222 rows containing missing values
#> (geom_point).
添加coord_equal()到ggplot会将X和Y轴的限制设置为相等。以下是无意义的示例。
ggplot(diamonds, aes(x=price, y=price+runif(nrow(diamonds), 100, 10000), color=cut)) +
geom_point() +
geom_smooth() +
coord_equal()
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
除了基本的ggplot2主题外,您还可以使用这些内置主题之一来更改绘图的外观。
该ggthemes软件包提供了模仿知名杂志和软件的其他ggplot主题。这是一个如何更改主题的示例。
ggplot(diamonds, aes(x=carat, y=price, color=cut)) +
geom_point() +
geom_smooth() +
theme_bw() +
labs(title="bw Theme") +
theme(plot.title = element_text(hjust = 0.5))
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
通过设置theme(legend.position="none"),您可以删除图例。通过将其设置为“top”,即theme(legend.position="top"),您可以在图上移动图例。通过legend.justification在绘图内设置坐标,可以将图例放置在绘图内。
p1 <- ggplot(diamonds, aes(x=carat, y=price, color=cut)) +
geom_point() +
geom_smooth() +
theme(legend.position="none",
plot.title = element_text(hjust = 0.5)) +
labs(title="legend.position='none'") # remove legend
p2 <- ggplot(diamonds, aes(x=carat, y=price, color=cut)) +
geom_point() +
geom_smooth() +
theme(legend.position="top") +
labs(title="legend.position='top'",
plot.title = element_text(hjust = 0.5)) # legend at top
p3 <- ggplot(diamonds, aes(x=carat, y=price, color=cut)) +
geom_point() +
geom_smooth() +
labs(title="legend.position='coords inside plot'") +
theme(legend.justification=c(1,0), legend.position=c(1,0),
plot.title = element_text(hjust = 0.5)) # legend inside the plot.
grid.arrange(p1, p2, p3, ncol=3) # arrange
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
ggplot(mtcars, aes(x=cyl)) +
geom_bar(fill='darkgoldenrod2') +
theme(panel.background = element_rect(fill = 'steelblue'))
ggplot(mtcars, aes(x=cyl)) +
geom_bar(fill='darkgoldenrod2') +
theme(panel.background = element_rect(fill = 'steelblue'),
panel.grid.major = element_line(colour = "firebrick", size=3),
panel.grid.minor = element_line(colour = "blue", size=1))
ggplot(mtcars, aes(x=cyl)) +
geom_bar(fill="firebrick")
ggplot(mtcars, aes(x=cyl)) +
geom_bar(fill="firebrick") +
theme(plot.background=element_rect(fill="steelblue"),
plot.margin = unit(c(2, 4, 1, 3), "cm")) # top, right, bottom, left
library(grid)
my_grob = grobTree(textGrob("This text is at x=0.1 and y=0.9, relative!\n Anchor point is at 0,0", x=0.1, y=0.9, hjust=0,
gp=gpar(col="firebrick", fontsize=25, fontface="bold")))
ggplot(mtcars, aes(x=cyl)) +
geom_bar() +
annotation_custom(my_grob) +
labs(title="Annotation Example")
plot1 <- ggplot(mtcars, aes(x=cyl)) +
geom_bar()
# ggsave("myggplot.png") # saves the last plot.
# ggsave("myggplot.png", plot=plot1) # save a stored ggplot