跳至主要内容

所有 R 用户都会问的 15 个绘图问题

R 的绘图类型多种多样,从基础图形到复杂的统计图形。本文将带您逐步创建这些图形。
· 15分钟 阅读

使用 AI 探索

explore datacamp's r course library banner

R 允许您创建不同的图形类型,从密度图、点图、箱线图和散点图等基础图形,到概率图等更复杂的统计图形。

此外,您可以从几乎不做定制的基础图,逐步到结合交互图形、可完全自定义的高级图形。然而,我们并不总能得到想要的 R 绘图效果:Stack Overflow 上充斥着关于绘图的问题,其中很多经常出现。

这正是 DataCamp 决定把所有常见问题及其高票答案汇总到一篇博文中的原因。

若想练习在 R 中创建图形,请试试这门 R 数据可视化课程。

15 个 R 绘图问题

1. 如何绘制一个空的 R 图形

打开一个新的绘图框架

You can open an empty plot frame and activate the graphics device in R as follows:
plot.new()

# Or try out the following command 
# frame()

注意,plot.new() 和 frame() 函数会定义一个没有坐标轴、标签或边框的新绘图框架,表示将要绘制一个新图:如果尚未打开图形窗口,将会打开新的窗口;否则会在现有窗口中准备新图。您可以在此处了解这些函数。

  • x11() 也可以在 R 中为 X Window System(版本 11)打开新的窗口设备!
  • quartz() 会为 OS X 系统启动图形设备驱动。

设置图形窗口的尺寸

您还可以使用 plot.window() 函数来设定刚创建的空图的横向和纵向范围:

plot.new()
pWidth = 3
pHeight = 2
plot.window(c(0,pWidth),
            c(0,pHeight))

绘制一个真正的空图

您可以用 plot() 函数绘制一个空图。另外,可使用 mtext() 和 title() 为空图添加坐标轴、坐标轴标签和标题。

# Draw an empty plot
plot(5, 
     5, 
     type="n", 
     axes=FALSE, 
     ann=FALSE, 
     xlim=c(0, 10), 
     ylim = c(0,10))

# Add text to the x-axis
mtext("x-axis", 
      side=1)

# Add text to the y-axis
mtext("y-axis",
      side=2) 

# Add a title
title("An R Plot")

您为图形提供了坐标 (5,5),但通过将 type 参数设为 "n" 来避免任何绘制。

提示:尝试将该参数设为 "p" 或 "b" 看看会发生什么!

此外,您没有为图形添加注释,但为 x 轴与 y 轴设定了从 0 到 10 的范围。

最后,您可以用 box() 在图形周围绘制一个边框,并用 points() 添加一些点:

# Draw an empty plot
plot(5, 
     5, 
     type="n", 
     axes=FALSE, 
     ann=FALSE, 
     xlim=c(0, 10), 
     ylim = c(0,10))

# Add text to the x-axis
mtext("x-axis", 
      side=1)

# Add text to the y-axis
mtext("y-axis",
      side=2) 

# Add a title
title("An R Plot")

#Draw a box
box()

#Put (red) point in the plot at (5,5)
points(5,
       5, 
       col="red") 
points(5, 
       7, 
       col="orange", 
       pch=3, 
       cex=2)
points(c(0, 0, 1), 
       c(2, 4, 6), 
       col="green", 
       pch=4)

注意,您可以将 x 坐标与 y 坐标放入向量,一次绘制多个点。pch 参数用于选择符号,而 cex 参数的值表示相对于默认值,应当将绘制的文本和符号缩放多少。

提示:若想查看数字与符号的对应关系,点击这里。

2. 如何设置 R 图形的坐标轴标签和标题

R 图形的坐标轴是 Stack Overflow 上最受关注的主题之一;与此相关的问题非常多样。

继续阅读,看看 DataCamp 发现哪些问题最为常见!

为坐标轴命名(含上标或下标)并为 R 图形添加标题?

您可以轻松地为坐标轴命名并添加标题,使 R 图形更具体、更易于读者理解。

只需在绘图函数中添加参数:main 表示主标题,sub 表示副标题,xlab 表示 x 轴标签,ylab 表示 y 轴标签。

注意,如果希望标题包含上标或下标,可以在 plot() 函数的 main 参数中直接添加。请使用 expression(),上标用 ^,下标用方括号。

在下方的 DataCamp Light 模块中试一试:

# The data
x <- seq(0,2*pi,0.1)
y <- sin(x)

# Plot the data
plot(x,
     y,
     main=expression("main title"^2), 
     sub=expression("sub-title"[2]), 
     xlab="x-axis label", 
     ylab="y-axis label")

您还可以结合 expression() 与 paste(),在坐标轴标签中加入希腊字母。运行以下代码:

# The data
x <- seq(0,2*pi,0.1)
y <- sin(x)

# Plot the data
plot(x,
     y,
     xlab = expression(paste("Greek letter ", phi)),
     ylab = expression(paste("Greek letter ",mu)))

调整坐标轴标签的外观

To adjust the appearance of the x-and y-axis labels, you can use the arguments col.lab and cex.lab. The first argument is used to change the color of the x-and y-axis labels, while the second argument is used to determine the size of the x-and y-axis labels, relative to the (default) setting of cex.
# The data
x <- seq(0,2*pi,0.1)
y <- sin(x)

# Plot the data
plot(x,
     y,
     main=expression("main title"^2), 
     sub=expression("sub-title"[2]), 
     xlab="x-axis label", 
     ylab="y-axis label",
     col.lab="blue",
     cex.lab=0.75)

关于这些参数的更多信息,请访问此页。

移除图形的坐标轴标签与注释

如果想去除图形的坐标轴刻度值,可以先添加参数 xaxt 与 yaxt,并设为 "n"。这些参数指定轴的类型;当设为 "n" 时,将抑制该轴的绘制。

注意,当为 xaxt 与 yaxt 传入其他字符时,将会绘制相应的坐标轴。

Next, you can add the annotation argument ann and set it to FALSE to make sure that any axis labels are removed.
# The data
x <- seq(0,2*pi,0.1)
y <- sin(x)

# Plot the data
plot(x,
     y,
     xaxt="n",
     yaxt="n",
     ann=FALSE)

提示:不是您要找的信息?请访问此页。

旋转图形的坐标轴刻度标签

You can add the las argument to the axis() function to rotate the numbers that correspond to each axis:
# The data
x <- seq(0,2*pi,0.1)
y <- sin(x)

# Plot the data, no axes
plot(x,
     y, 
     axes=FALSE)

# Draw a box
box()

# Add (modified) axes to the plot
axis(2, 
     las=2)
axis(1, 
     las=0)

注意,这实际上需要您在 plot() 中先声明不绘制坐标轴(暂时):随后由两个 axis() 来完成绘制。

las 参数可取四种值。根据选择,标签的放置会不同:0 表示标签始终与轴平行(默认);1 表示水平放置;2 表示与轴垂直;3 表示竖直放置。

此外,如果您想了解 axis() 的更多用法,请继续阅读!

移动 R 图形的坐标轴

想改变坐标轴的位置?

可以使用 axis();正如您在本教程前面所见,该函数允许您指定轴绘制在哪一侧。假设您想把 x 轴放在绘图区上方、y 轴放在右侧。

请记住,向 axis() 传入 1 或 2,分别在底部与左侧绘制坐标轴。向上滚动可查看前面代码中的示例!

This means that you will want to pass 3 and 4 to the axis() function:
# The data
x<-seq(0,2*pi,0.1)
y<-sin(x)

# Plot the data, but don't plot axes or annotations
plot(x,
     y,
     axes=FALSE, 
     ann=FALSE)

# Draw the x-axis above the plot area
axis(3)

# Draw the y-axis to the right of the plot area
axis(4)

# Draw a box
box()

如您所见,首先绘制 x 和 y,但省略坐标轴与注释;然后添加所需的坐标轴,并指定它们相对于绘图区的位置。

axis() 带来的灵活性还不止于此!查看下一个常见问题,看看这个基础函数还能解决什么。

提示:前往最后一个问题,了解如何用 hjust 和 vjust 在坐标轴标签中移动文本!

3. 如何添加并更改 R 图形刻度线的间距

如何更改 R 图形刻度线的间距

让 R 自动决定刻度线有时会让人头疼,总有时候您会想要调整它们。

1. 使用 axis() 来确定图形的刻度线

Consider the following piece of code:
# Define the position of tick marks
v1 <- c(0,pi/2,pi,3*pi/2,2*pi)

# Define the labels of tick marks
v2 <- c("0","Pi/2","Pi","3*Pi/2","2*Pi")

# The data
x <- seq(0,2*pi,0.1)
y <- sin(x)

# Plot the data
plot(x,
     y,
     xaxt = "n")

# Add an axis to the plot 
axis(side = 1, 
     at = v1, 
     labels = v2,
     tck=-.05)

如上,您先定义刻度线的位置与标签。然后绘制图形,并将 x 轴类型设为 "n",以抑制坐标轴的绘制。

接下来是关键步骤:

  • axis() 允许您指定绘制坐标轴的方位。本例中参数为 1,表示在下方绘制。若为 2,则在左侧;若为 3 或 4,则分别在上方或右侧;
  • at 参数用于指明刻度线绘制的位置。本例使用在 V1 中定义的位置;
  • 同样,labels 使用在 V2 中指定的标签;
  • 通过 tck 调整刻度线方向:当为负值时,刻度线绘制在坐标轴下方。

提示:尝试给 tck 传入正值,看看会怎样!

You can further specify the size of the ticks through tcl and the appearance of the tick labels is controlled with cex.axis, col.axis and font.axis.
# Define the position of tick marks
v1 <- c(0,pi/2,pi,3*pi/2,2*pi)

# Define the labels of tick marks
v2 <- c("0","Pi/2","Pi","3*Pi/2","2*Pi")

# The data
x <- seq(0,2*pi,0.1)
y <- sin(x)

# Plot the data
plot(x,
     y,
     xaxt = "n")

# Add axis to the plot 
axis(side = 1, 
     at = v1, 
     labels = v2,
     tck=-.1,
     tcl = -0.5,
     cex.axis=1.05,
     col.axis="blue",
     font.axis=5)

2. 使用其他函数确定 R 图形的刻度线

您也可以用 par() 与 plot() 来定义刻度线位置及其间的分隔数。

注意,此时使用参数 xaxp,传入 x 轴两端刻度线的位置,随后是它们之间的区间数:
# The data
x <- seq(0,2*pi,0.1)
y <- sin(x)

# Plot the data
plot(x,
     y,
     xaxp = c(0, 2*pi, 5))

您也可以运行以下代码,基本得到相同结果:

# The data 
x <- seq(0,2*pi,0.1)
y <- sin(x)

# Plot the data 
plot(x, 
     y, 
     xaxt="n")

# Use `par()` to set graphical `xaxp` parameter
par(xaxp= c(0, 2*pi, 2)) 

# Add an axis to the plot 
axis(1)

注意,这仅在不使用对数坐标时有效。如果 log 坐标开启(即 par(xlog=T)),传递给 xaxp 的三个值含义不同:当范围很小时,n 为负;否则 n 取 1 到 3,表示情况编号,x1 与 x2 为用户坐标内的 10 的最小与最大幂,即 10 ^ par(“usr”)[1:2]。

一个示例:
n <- 1

# The data
x <- seq(0, 10000, 1)
y <- exp(n)/(exp(n)+x)

# Set graphical parameters `xlog` and `xaxp`
par(xlog=TRUE, 
    xaxp= c(1, 4, 3))

# Pot the data 
plot(x, 
     y, 
     log="x") 

在该示例中,您使用 par() 将 xlog 设为 TRUE,并添加 xaxp 来指定两端刻度线坐标及其间的区间数:此处最小值为 1,最大值为 4,每段之间有 3 个区间。

随后绘制 x 与 y,并通过 log 参数指定在对数尺度上绘制 x 轴、y 轴或两者。为此可将 "x"、"y" 或 "xy" 传入该参数。

两个轴均为对数尺度的示例:
n <- 1

# The data
x <- seq(0, 20, 1)
y <- exp(x)/(x)

# Set graphical parameters `xlog` and `yaxp`
par(xlog=TRUE, 
    xaxp= c(1, 4, 3))
# Set graphical parameters `ylog` and `yaxp`
par(ylog=TRUE, 
    yaxp= c(1, 11, 2)) 

# Plot the data 
plot(x, 
     y, 
     log="xy")

如何为 R 图形添加次刻度线

You can quickly add minor tick marks to your plot with the minor.tick() function from the Hmisc package:
# Import `Hmisc` library
library(Hmisc)

# Make a new plot
plot.new()

# Set minor tick mark
minor.tick(nx = 1.5, 
           ny = 2, 
           tick.ratio=0.75)
  • nx 参数指定希望在主刻度线之间划分的区间数。若传入 1,则会抑制次刻度线;
  • ny 与 nx 类似,但用于 y 轴;
  • tick.ratio 表示次刻度线与主刻度线长度的比率。主刻度线长度从 par(tck=x) 获取。

4. 如何创建两个不同的 X 或 Y 轴

The first option is to create a first plot and to execute the par() function with the new argument put to TRUE to prevent R from clearing the graphics device:
# Set a seed 
set.seed(101)

# The data
x <- 1:10
y <- rnorm(10)
z <- runif(10, min=1000, max=10000)

# Plot the data
plot(x, y) 

# Don't clean the frame before drawing
par(new = TRUE)

然后,使用 plot() 创建第二个图。传入数据,并确保调整一些参数,如 type、axes、bty、xlab 和 ylab:

  • type:传入 l 以绘制折线;
  • axes 设为 FALSE,不绘制坐标轴;
  • bty 抑制绘图区边框;
  • xlab 设为空字符串,这样 x 轴无标签;
  • ylab 也设为空字符串,这样 y 轴无标签。

在下面的 DataCamp Light 模块中查看全部内容。注意,上面的代码已加载到您的工作环境中。您可以在右侧的 R 控制台中检查:

plot(x, 
     z, 
     type = "l", 
     axes = FALSE,
     bty = "n", 
     xlab = "", 
     ylab = "")

接下来,分别使用 axis() 和 mtext() 添加坐标轴并在边距处写入文字。

您可以通过向 axis() 的 side 参数传入 4,在右侧添加新坐标轴。然后,通过 at 指定刻度线位置。本例中,使用 pretty() 对 z 的范围计算 n+1 个等距的“圆整”值,确保这些刻度正好对应第二个图(z)的 y 轴数值。

在下方试一试:

axis(side=4, 
     at = pretty(range(z)))
mtext("z", 
      side=4, 
      line=3)

注意,side 参数可取四值:1 表示底部,2 左侧,3 顶部,4 右侧。line 参数表示文字从第几条边距线开始。

最终代码的结果如下:

set.seed(101)
x <- 1:10
y <- rnorm(10)
z <- runif(10, min=1000, max=10000)
plot(x, y) 
par(new = TRUE)
plot(x, 
     z, 
     type = "l", 
     axes = FALSE, 
     bty = "n", 
     xlab = "", 
     ylab = "")
axis(side=4, 
     at = pretty(range(z)))
mtext("z", 
      side=4, 
      line=3)

作为额外练习,试着构建一个拥有两个不同 x 轴的 R 图形!请在下方的 DataCamp Light 模块中完成:

plot.new()
set.seed(101)
x <- 1:10
y <- rnorm(10)
z <- runif(10, min=1000, max=10000) 
par(mar = c(5, 4, 4, 4) + 0.3)
plot(x, y)
par(new = TRUE)
plot(z, y, type = "l", axes = FALSE, bty = "n", xlab = "", ylab = "")
axis(side=3, at = pretty(range(z)))
mtext("z", side=3, line=3)

请注意,尽管可以用基础的 plot()、axis() 和 mtext() 手动完成上述操作,但也有包可以将其自动化:plotrix 包的 twoord.plot() 与 latticeExtra 包的 doubleYScale() 都很方便,如果要做相同的事情可能更快:

# Import `latticeExtra`
library(latticeExtra)

# The data
chol <- read.table(url("http://assets.datacamp.com/blog_assets/chol.txt"), header = TRUE)
Age <- chol$AGE
Chol <- chol$CHOL
Smoke <- chol$SMOKE
State <- chol$MORT

# Create a bivariate scatterplot `a` 
a <- xyplot(Chol ~ Age|State)

# Create a bivariate scatterplot `b` 
b <- xyplot(Smoke ~ Age|State)

# Draw the two plots with different y scales 
doubleYScale(a, b, style1 = 0, style2 = 3, add.ylab2 = TRUE, columns=3)

注意,上述示例使用了该数据集。如果对数据导入或 read.table() 有疑问,请查看 DataCamp 关于在 R 中导入数据的教程。

5. 如何添加或更改 R 图形的图例

使用基础 R 添加与更改图例

You can easily add a legend to your R plot with the legend() function:
# The data
x <- seq(0,pi,0.1)
y1 <- cos(x)
y2 <- sin(x)

# Plot 
plot(c(0,3), c(0,3), type="n", xlab="x", ylab="y")

# Draw lines
lines(x, y1, col="red", lwd=2)
lines(x, y2, col="blue", lwd=2)

# Add legend to plot 
legend("topright", 
       inset=.05, 
       cex = 1, 
       title="Legend", 
       c("Cosinus","Sinus"), 
       horiz=TRUE, 
       lty=c(1,1), 
       lwd=c(2,2), 
       col=c("red","blue"), 
       bg="grey96")

请注意,文档中提到的 legend() 的 pt.cex 和 title.cex 实际效果并不好。可以采用以下变通方法:

  1. 通过向 legend() 添加 text.font,用不同字体显示图例的标题或标签:
# The data
x <- seq(0,pi,0.1)
y1 <- cos(x)
y2 <- sin(x)

# Plot 
plot(c(0,3), c(0,3), type="n", xlab="x", ylab="y")

# Draw lines
lines(x, y1, col="red", lwd=2)
lines(x, y2, col="blue", lwd=2)

# Add legend
legend("topright", 
       inset=.05, 
       cex = 1, 
       title="Legend", 
       c("Cosinus","Sinus"), 
       horiz=TRUE, 
       lty=c(1,1), 
       lwd=c(2,2), 
       col=c("red","blue"), 
       bg="grey96",
       text.font=3)
  1. 用不同的 cex 值绘制两次图例
# The data
x <- seq(0,pi,0.1)
y1 <- cos(x)
y2 <- sin(x)

# Plot
plot(c(0,3), c(0,3), type="n", xlab="x", ylab="y")

# Draw lines
lines(x, y1, col="red", lwd=2)
lines(x, y2, col="blue", lwd=2)

# Add subtitles for legend
legend("topright",
       inset=.05,
       cex = 0.75,
       c("Cosinus","Sinus"),
       title="",
       horiz=TRUE,
       lty=c(1,1), 
       lwd=c(2,2), 
       col=c("red","blue"))

# Add title to legend 
legend(2.05, 2.97, 
       inset=.05,
       c("",""),
       title="Legend",
       cex=1.15, 
       bty="n")

提示:若想了解 R 可用颜色,查看这份非常实用的 PDF 文档。

在 ggplot2 中添加与更改图例和标签

Adding a legend to your ggplot2 plot is fairly easy. You can just execute the following:
# Load in `ggplot2`
library(ggplot2)

# Read in the data
chol <- read.table(url("http://assets.datacamp.com/blog_assets/chol.txt"), 
                   header = TRUE)

# Plot the data 
ggplot(chol, aes(x=chol$WEIGHT, 
                 y=chol$HEIGHT)) + 
  geom_point(aes(colour = factor(chol$MORT), 
                 shape=chol$SMOKE)) + 
  xlab("Weight") + 
  ylab("Height") 

它会生成一个默认图例。但多数情况下,您还会希望进一步调整图例的外观。

在 ggplot2 中更改图例标题与标签有两种方法:

  1. 告知尺度使用不同的标题与标签
If you have specified arguments such as colour or shape, or other aesthetics, you need to change the names and labels through the scale_color_discrete() and scale_shape_discrete() functions, respectively:
# Load in `ggplot2`
library(ggplot2)

# Read in data
chol <- read.table(url("http://assets.datacamp.com/blog_assets/chol.txt"), 
                   header = TRUE)

# Plot the data
ggplot(chol, aes(x=chol$WEIGHT, 
                 y=chol$HEIGHT)) + 
  geom_point(aes(colour = factor(chol$MORT), 
                 shape = chol$SMOKE)) + 
  xlab("Weight") + 
  ylab("Height") + 
  theme(legend.position=c(1,0.5),
        legend.justification=c(1,1)) + 
  scale_color_discrete(name ="Condition", 
                       labels=c("Alive", "Dead")) +
  scale_shape_discrete(name="Smoker", 
                       labels=c("Non-smoker", "Sigare", "Pipe" ))

请注意,DataCamp Light 的 Plot 面板中图形可能略显拥挤,但如果在 RStudio 中执行则不会有问题。

注意,如果在 geom_point() 中添加了 shape 参数,并在 labels 中指定相应标签,您可以创建两个图例!

若想将图例移动到图形底部,可以将 legend.position 设为 "bottom"。另一方面,legend.justification 可将图例定位到绘图区内部。

提示:查看 这里,了解可用于告知 ggplot 使用其他名称和标签的各种尺度函数。

  1. 更改数据框,使因子具有期望的形式
例如:
# Read in data
chol <- read.table(url("http://assets.datacamp.com/blog_assets/chol.txt"), header = TRUE)

# Manipulate the data
levels(chol$SMOKE)[levels(chol$SMOKE)=="Non-smoker"] <- "Non-smoker"
levels(chol$SMOKE)[levels(chol$SMOKE)=="Sigare"] <- "Sigare"
levels(chol$SMOKE)[levels(chol$SMOKE)=="Pipe"] <- "Pipe"
names(chol)[names(chol)=="SMOKE"]  <- "SMOKER"

# Inspect result 
head(chol)

随后,您可以直接使用新的因子名称在 ggplot2 中绘图,避免在绘图代码中再额外修改名称与标签的“麻烦”。

提示:完整的 ggplot2 速查表见这里。

6. 如何在 R 图形中绘制网格

使用基础 R 在图形中绘制网格

For some purposes, you might find it necessary to include a grid in your plot. You can easily add a grid to your plot by using the grid() function:
# Data
x <- c(1,2,3,4,5)
y <- 2*x

# Plot
plot(x,y)

# Grid
grid(10,10)

在 ggplot2 中绘制网格

下面的代码演示如何使用 ggplot2 让图形显示网格。注意,chol 数据已加载,并且已按前文步骤做了处理。

如果不确定数据长什么样,请在 DataCamp Light 模块的 R 控制台中打印数据框的前几行:

# Load in `ggplot2`
library(ggplot2)

# Plot data 
ggplot(chol, aes(x=chol$WEIGHT, y=chol$HEIGHT)) + 
  geom_point(aes(colour = factor(chol$MORT), shape = chol$SMOKE)) + 
  xlab("Weight") + 
  ylab("Height") + 
  theme(panel.grid.major = element_line(colour = "grey40"),
        panel.grid.minor = element_line(colour = "grey40"))

提示:如果不想显示次级网格线,只需将 panel.grid.minor 设为 element_blank()。

如果想将背景填充为某种颜色,添加 panel.background = element_rect(fill = "navy") 即可。下方的 DataCamp Light 模块展示了如何实现。同样,chol 数据已按前述进行简单处理。亲自试一试!

library(ggplot2)
ggplot(chol, aes(x=chol$WEIGHT, y=chol$HEIGHT)) + 
  geom_point(aes(colour = factor(chol$MORT), shape = chol$SMOKER)) + 
  xlab("Weight") + 
  ylab("Height") + 
  scale_color_discrete(name ="Condition", labels=c("Alive", "Dead")) +
  scale_shape_discrete(name="Smoker", labels=c("Non-smoker", "Sigare", "Pipe" )) +
  theme(legend.position=c(1,0.5),
        legend.justification=c(1,1),
        panel.grid.major = element_line(colour = "grey40"),
        panel.grid.minor = element_line(colour = "grey40"),
        panel.background = element_rect(fill = "navy")
        )

7. 如何以 PNG 作为背景绘制图形

您可以借助 png 包,快速将 .png 图片作为背景来绘图。若有需要请先安装并通过 library() 激活,然后开始绘图!

首先需要加载图片。使用 readPNG() 指定图片路径!

提示:您可以通过执行以下命令查看并更改工作目录。

如果图片保存在工作目录下,只需写 readPNG("picture.png"),无需提供完整路径。

接着,设置绘图区域,并调用 rasterImage() 时通过 par() 设置图形参数。使用 usr 定义绘图区域用户坐标的范围。本例中设为 1、3、2 和 4。

然后绘制网格并添加几条折线:

install.packages("png")
library(png)
image <- readPNG("<path to your picture>")

getwd()
setwd("<path to a folder>")

plot(1:2, type='n', main="Plotting Over an Image", xlab="x", ylab="y")

lim <- par()

rasterImage(image, lim$usr[1], lim$usr[3], lim$usr[2], lim$usr[4])

grid()
lines(c(1, 1.2, 1.4, 1.6, 1.8, 2.0), c(1, 1.3, 1.7, 1.6, 1.7, 1.0), type="b", lwd=5, col="red")

如果使用 DataCamp 的标志,上述代码可能会得到如下效果:

library(png)
image <- readPNG("datacamp.png")
plot(1:2, type="n", main="Plotting Over an Image", xlab="x", ylab="y", asp=1)
lim <- par()
rasterImage(image, lim$usr[1], lim$usr[3], lim$usr[2], lim$usr[4])
lines(c(1, 1.2, 1.4, 1.6, 1.8, 2.0), c(1.5, 1.3, 1.7, 1.6, 1.7, 1.0), type="b", lwd=5, col="red")

Plotting over DataCamp logo

注意,readPNG() 的输入需要 .png 文件;如果想处理 jpg 图片,也可以采用同样的方法,但需加载 jpeg 库!

# Download an image
download.file("https://holtzyan.files.wordpress.com/2015/10/cropped-p1090518.jpg" , destfile="my_image.jpg")

# Load `jpeg` 
library(jpeg)

# Read in the jpg file 
my_image=readJPEG("my_image.jpg")

# Set up a plot area with no plot
plot(1:2, type='n', main="", xlab="x", ylab="y")

# Get the plot information
lim <- par()
rasterImage(my_image, lim$usr[1], lim$usr[3], lim$usr[2], lim$usr[4])
grid()

#Add your plot
lines(c(1, 1.2, 1.4, 1.6, 1.8, 2.0), c(1, 1.3, 1.7, 1.6, 1.7, 1.0), type="b", lwd=5, col="white")

注意,在此示例中,您先从网络下载一张图片用于绘图;当然也可以直接保存图片并将文件路径传给 readJPEG() 来使用。

另外,本示例摘自 R Graph Gallery,该网站为 R 数据可视化提供了大量灵感,代码与渲染效果一应俱全!如果您在寻找灵感或需要快速找到绘图所需代码,它非常适合。

8. 如何调整 R 图形中点的大小

使用基础 R 调整点的大小

To adjust the size of the points with basic R, you might just simply use the cex argument:
x <- c(1,2,3,4,5)
y <- c(6,7,8,9,10)

plot(x,y,cex=2,col="red")
请记住,R 还允许通过 symbols() 对符号进行更细致的控制:
df <- data.frame(x1=1:10, 
                 x2=sample(10:99, 10), 
                 x3=10:1)
symbols(x=df$x1, 
        y=df$x2, 
        circles=df$x3, 
        inches=1/3, 
        ann=F, 
        bg="steelblue2", 
        fg=NULL)

该图中的圆将 df$x3 的数值作为半径,而 inches 参数用来控制符号大小。当该参数为正数时,符号会缩放,使其最大边长等于指定的英寸数。

在 ggplot2 中调整散点大小

本例中,您将调整散点图中点的大小。可以使用 size 参数。注意,chol 数据已为您加载:
library(ggplot2)

ggplot(chol, 
       aes(x=chol$WEIGHT, y=chol$HEIGHT), 
       size = 2) + 
  geom_point()

注意,也可以将 size 参数传给 geom_point():

ggplot(chol, 
       aes(x=chol$WEIGHT, y=chol$HEIGHT)) + 
  geom_point(size = 2)

您将得到相同的结果。不妨在上方模块中用该代码替换最后一段自行验证。

9. 如何为 R 数据拟合平滑曲线

loess() 大概是此类问题中每位 R 程序员的心头好。它“使用局部拟合,基于一个或多个数值型自变量来拟合一个多项式曲面”。

简而言之,拿到数据后使用 loess() 关联 y 与 x,从而指定数值型应变量和 1 到 4 个数值型自变量。

接着绘制 x 与 y,并在原图上绘制由 lo 预测得到的曲线:
x <- 1:10
y <- c(2,4,6,8,7,12,14,16,18,20)

#Estimations between data
lo <- loess(y~x)

plot(x,y)

lines(predict(lo))

10. 如何在 R 图形中添加误差线

使用基础 R 绘制误差线

坏消息是:R 不能直接绘制误差线。好消息是:无需安装额外包也能画!

首先,您需要定义以下函数来计算数据框的一些汇总统计量:

summarySE <- function(data=NULL, measurevar, groupvars=NULL, na.rm=FALSE,
                      conf.interval=.95, .drop=TRUE) {
    library(plyr)

    # New version of length which can handle NA's: if na.rm==T, don't count them
    length2 <- function (x, na.rm=FALSE) {
        if (na.rm) sum(!is.na(x))
        else       length(x)
    }

    # This does the summary. For each group's data frame, return a vector with
    # N, mean, and sd
    datac <- ddply(data, groupvars, .drop=.drop,
      .fun = function(xx, col) {
        c(N    = length2(xx[[col]], na.rm=na.rm),
          mean = mean   (xx[[col]], na.rm=na.rm),
          sd   = sd     (xx[[col]], na.rm=na.rm)
        )
      },
      measurevar
    )

    # Rename the "mean" column    
    datac <- rename(datac, c("mean" = measurevar))

    datac$se <- datac$sd / sqrt(datac$N)  # Calculate standard error of the mean

    # Confidence interval multiplier for standard error
    # Calculate t-statistic for confidence interval: 
    # e.g., if conf.interval is .95, use .975 (above/below), and use df=N-1
    ciMult <- qt(conf.interval/2 + .5, datac$N-1)
    datac$ci <- datac$se * ciMult

    return(datac)
}

请注意,该函数定义来自此来源,也可通过 Rmisc 库获得。

接下来,您可用它来计算 chol 数据(已为您加载)的一些统计量;然后基于这些结果作图。

在开始练习前,请先检查数据!

#Calculate some statistics for the `chol` dataset
cholc <- summarySE(chol, 
                   measurevar="CHOL", 
                   groupvars=c("MORT",
                               "SMOKER"))
#Plot the data
plot(cholc$N, 
     cholc$CHOL,
     ylim=range(c(cholc$CHOL-cholc$sd, 
                  cholc$CHOL+cholc$sd)),
     pch=19, 
     xlab="Cholesterol Measurements", 
     ylab="Cholesterol Mean +/- SD",
     main="Scatterplot With sd Error Bars"
)

#Draw arrows of a "special" type
arrows(cholc$N, 
       cholc$CHOL-cholc$sd, 
       cholc$N, 
       cholc$CHOL+cholc$sd, 
       length=0.05, 
       angle=90, 
       code=3)

如果想了解 arrows() 可接收的所有参数,请访问这里。

使用 ggplot2 绘制误差线

表示均值标准误(SE)的误差线

先使用 summarySE()(来自 Rmisc 包)或上文定义的函数汇总数据。然后将得到的数据框用于绘图,同时绘制误差线,例如以均值标准误为误差。

为方便演示,数据与函数已为您加载:
#Calculate some statistics for the chol dataset
cholc <- summarySE(chol, 
                   measurevar="CHOL", 
                   groupvars=c("MORT",
                               "SMOKER"))

#Plot the cholc dataset
library(ggplot2)
ggplot(cholc, aes(x=SMOKER, 
                  y=CHOL, 
                  colour=MORT)) + 
    geom_errorbar(aes(ymin=CHOL-se, 
                      ymax=CHOL+se, 
                      group=MORT), 
                  width=.1) +
    geom_line(aes(group=MORT)) +
    geom_point()
如果想调整误差线的位置(例如,当它们重叠时),可以考虑使用 position_dodge():

提示:若出现 “geom_path: Each group consist of only one observation. Do you need to adjust the group aesthetic?” 类似错误,通常需要调整分组映射。

表示置信区间的误差线

延续上一节中用 summarySE()(Rmisc)得到的汇总数据,也可以绘制表示置信区间的误差线。下面示例绘制的是 95% 置信区间。

注意,此时通过 colour 参数将误差线的颜色设为黑色。

表示标准差(SD)的误差线

最后,您也可以使用 summarySE()(Rmisc)的结果,或前文复制的函数定义,来绘制表示标准差的误差线。

具体而言,只需调整传递给 geom_errorbar() 的 ymin 与 ymax 参数:

#Calculate some statistics for the chol dataset
cholc <- summarySE(chol, 
                   measurevar="CHOL", 
                   groupvars=c("MORT","SMOKER"))

#Plot the cholc dataset
library(ggplot2)
pd <- position_dodge(0.1)
ggplot(cholc, aes(x=SMOKER, 
                  y=CHOL, 
                  colour=MORT)) + 
    geom_errorbar(aes(ymin=CHOL-sd, 
                      ymax=CHOL+sd, 
                      group=MORT), 
                  width=.1,
                  position=pd) +
    geom_line(aes(group=MORT)) +
    geom_point()

重要提示:更多有关均值与误差线绘图的详细示例,请参阅这里。

11. 如何将图形保存为磁盘上的图片

您可以使用 dev.copy() 将当前图形设备中的图复制到您指定的设备或文件夹中。

x <- seq(0,2*pi,0.1)
y <- sin(x)
plot(x,y)
dev.copy(jpeg,
         filename="<path to your file/name.jpg>");
dev.off();
(x)
(y)

12. 如何将两个 R 图形并排绘制

使用基础 R 将两幅图并排绘制

You can do this with basic R commands:
# Data
d0 <- matrix(rnorm(15), ncol=3)
d1 <- matrix(rnorm(15), ncol=3)

# Set limits 
limits <- range(d0,d1)

# Set graphical parameter `mfrow`
par(mfrow = c(1, 2)) 

# Make 2 boxplots
boxplot(d0,
        ylim=limits)
boxplot(d1,
        ylim=limits)

通过 par() 中的 mfrow 参数,您可以指定一个向量(此处为 1 与 2):所有图形将按行的顺序绘制在一个 1 行 2 列的布局中(mfrow)。

换言之,上述箱线图将印在同一行的两个列中。

使用 ggplot2 将两幅图并排绘制

如果想将图形并排显示,又不想手动指定范围,可以考虑使用 ggplot2 来并排绘图。

您的 chol 数据与 summarySE() 函数已加载。如不确定其结构,请在 R 控制台中查看:

主题