【r<-ggplot2】条形图与线图

问题

你想要创建基本的条形图与线图

方案

想要使用ggplot2绘制图形,数据必须是一个数据框,而且必须是长格式。

基本图形,离散x-axis

使用条形图,条形的高度通常代表这种不同的东西:

  • 每一组事件的计数,通过stat_bin指定,ggplot2默认使用该选项
  • 数据集中某一列的,通过stat_identity指定
x axis 高度含义 Common name
连续 计数 直方图
离散 计数 条形图
连续 数值 条形图
离散 数值 条形图
有值的条形图

这里有一些样例数据 (抽自reshape2包的 tips 数据集):

dat <- data.frame(
  time = factor(c("Lunch","Dinner"), levels=c("Lunch","Dinner")),
  total_bill = c(14.89, 17.23)
)
dat
#>     time total_bill
#> 1  Lunch      14.89
#> 2 Dinner      17.23

# Load the ggplot2 package
library(ggplot2)

在这些例子中,条形的高度代表数据框某一列的,所以使用stat="identity" 而不是默认的stat="bin"

这里使用的映射变量为:

  • time: x-axis 和有时填充颜色
  • total_bill: y-axis
# 非常基本的条形图
ggplot(data=dat, aes(x=time, y=total_bill)) +
    geom_bar(stat="identity")


# 按时间填充颜色
ggplot(data=dat, aes(x=time, y=total_bill, fill=time)) +
    geom_bar(stat="identity")

## 这和上面是一样的结果
# ggplot(data=dat, aes(x=time, y=total_bill)) +
#    geom_bar(aes(fill=time), stat="identity")


# 添加黑色的边框线
ggplot(data=dat, aes(x=time, y=total_bill, fill=time)) +
    geom_bar(colour="black", stat="identity")


# 没有图例,因为这个信息是多余的
ggplot(data=dat, aes(x=time, y=total_bill, fill=time)) +
    geom_bar(colour="black", stat="identity") +
    guides(fill=FALSE)

一个理想的条形图可能是下面这样的:

# 添加题目,缩小箱宽,填充颜色,改变轴标签
ggplot(data=dat, aes(x=time, y=total_bill, fill=time)) + 
    geom_bar(colour="black", fill="#DD8888", width=.8, stat="identity") + 
    guides(fill=FALSE) +
    xlab("Time of day") + ylab("Total bill") +
    ggtitle("Average bill for 2 people")

参见 ../Colors (ggplot2) 获取更多关于颜色的信息。

计数的条形图

在下面例子中,条形高度代表事件的计数。

我们直接使用reshape2tips数据集。

library(reshape2)
# 查看头几行
head(tips)
#>   total_bill  tip    sex smoker day   time size
#> 1      16.99 1.01 Female     No Sun Dinner    2
#> 2      10.34 1.66   Male     No Sun Dinner    3
#> 3      21.01 3.50   Male     No Sun Dinner    3
#> 4      23.68 3.31   Male     No Sun Dinner    2
#> 5      24.59 3.61 Female     No Sun Dinner    4
#> 6      25.29 4.71   Male     No Sun Dinner    4

想要得到一个计数的条形图,不要映射变量到y,使用 stat="bin" (默认就是这个) 而不是stat="identity":

# 计数的条形图
ggplot(data=tips, aes(x=day)) +
    geom_bar(stat="count")
## 和上面等同, 因为stat="bin"是默认
# ggplot(data=tips, aes(x=day)) +
#    geom_bar()

线图

对于线图,数据点必须分组从而R知道怎么连接这些点。如果只有一组的话,非常简单,设定group=1即可,如果是多组,需要设定分组变量。

下面是使用的映射变量

  • time: x-axis
  • total_bill: y-axis
# 基本的线图
ggplot(data=dat, aes(x=time, y=total_bill, group=1)) +
    geom_line()
## This would have the same result as above
# ggplot(data=dat, aes(x=time, y=total_bill)) +
#     geom_line(aes(group=1))

# 添加点
ggplot(data=dat, aes(x=time, y=total_bill, group=1)) +
    geom_line() +
    geom_point()

# 改变线和点的颜色
# 改变线的类型和点的类型,用更粗的线、更大的点
# 用红色填充点
ggplot(data=dat, aes(x=time, y=total_bill, group=1)) + 
    geom_line(colour="red", linetype="dashed", size=1.5) + 
    geom_point(colour="red", size=4, shape=21, fill="white")

理想的线图可能像下面这样:

# 设定y轴的范围
# 改变轴标签
ggplot(data=dat, aes(x=time, y=total_bill, group=1)) +
    geom_line() +
    geom_point() +
    expand_limits(y=0) +
    xlab("Time of day") + ylab("Total bill") +
    ggtitle("Average bill for 2 people")

有更多变量的图

下面这个数据将用于接下来的例子

dat1 <- data.frame(
    sex = factor(c("Female","Female","Male","Male")),
    time = factor(c("Lunch","Dinner","Lunch","Dinner"), levels=c("Lunch","Dinner")),
    total_bill = c(13.53, 16.81, 16.24, 17.42)
)
dat1
#>      sex   time total_bill
#> 1 Female  Lunch      13.53
#> 2 Female Dinner      16.81
#> 3   Male  Lunch      16.24
#> 4   Male Dinner      17.42

条形图

变量映射:

  • time: x-axis
  • sex: color fill
  • total_bill: y-axis.
# 堆积条形图 -- 不常用
ggplot(data=dat1, aes(x=time, y=total_bill, fill=sex)) +
    geom_bar(stat="identity")

# 条形图,x轴是time,颜色填充是sex 
ggplot(data=dat1, aes(x=time, y=total_bill, fill=sex)) +
    geom_bar(stat="identity", position=position_dodge())

ggplot(data=dat1, aes(x=time, y=total_bill, fill=sex)) +
    geom_bar(stat="identity", position=position_dodge(), colour="black")

# 改变颜色
ggplot(data=dat1, aes(x=time, y=total_bill, fill=sex)) +
    geom_bar(stat="identity", position=position_dodge(), colour="black") +
    scale_fill_manual(values=c("#999999", "#E69F00"))

改变映射是非常容易的

# 条形图,x轴是性别,颜色是时间
ggplot(data=dat1, aes(x=sex, y=total_bill, fill=time)) +
    geom_bar(stat="identity", position=position_dodge(), colour="black")

线图

变量映射:

  • time: x-axis
  • sex: line color
  • total_bill: y-axis.

想要绘制多条线,必须指定分组变量。

# 基本的带点线图
ggplot(data=dat1, aes(x=time, y=total_bill, group=sex)) +
    geom_line() +
    geom_point()

# 将性别映射到颜色
ggplot(data=dat1, aes(x=time, y=total_bill, group=sex, colour=sex)) +
    geom_line() +
    geom_point()

# 映射性别到不同的点类型
ggplot(data=dat1, aes(x=time, y=total_bill, group=sex, shape=sex)) +
    geom_line() +
    geom_point()


# 使用更粗的线、更大的点
ggplot(data=dat1, aes(x=time, y=total_bill, group=sex, shape=sex)) + 
    geom_line(size=1.5) + 
    geom_point(size=3, fill="white") +
    scale_shape_manual(values=c(22,21))

更改颜色和线型变量的映射非常容易:

ggplot(data=dat1, aes(x=sex, y=total_bill, group=time, shape=time, color=time)) +
    geom_line() +
    geom_point()

完成的例子

完成的例子可能像下面这样

# 一个条形图
ggplot(data=dat1, aes(x=time, y=total_bill, fill=sex)) + 
    geom_bar(colour="black", stat="identity",
             position=position_dodge(),
             size=.3) +                        # 更粗的线
    scale_fill_hue(name="Sex of payer") +      # 设定图例标题
    xlab("Time of day") + ylab("Total bill") + # 设定轴标签
    ggtitle("Average bill for 2 people") +     # 设定题目
    theme_bw()


# 一个线图
ggplot(data=dat1, aes(x=time, y=total_bill, group=sex, shape=sex, colour=sex)) + 
    geom_line(aes(linetype=sex), size=1) +     # 按性别设定线型
    geom_point(size=3, fill="white") +         # 使用更大的点,并用颜色填充
    expand_limits(y=0) +                       # 将0包含仅y轴
    scale_colour_hue(name="Sex of payer",      # 设定图例标题
                     l=30)  +                  # 使用更深的颜色 (lightness=30)
    scale_shape_manual(name="Sex of payer",
                       values=c(22,21)) +      # 
    scale_linetype_discrete(name="Sex of payer") +
    xlab("Time of day") + ylab("Total bill") + # 设定轴标签
    ggtitle("Average bill for 2 people") +     # 设定标题
    theme_bw() +
    theme(legend.position=c(.7, .4))           # 图例的位置
                                              

为了保证上图的图例一致,必须指定3次。至于为何如此,点击 这里

使用数值 x-axis

datn <- read.table(header=TRUE, text='
supp dose length
  OJ  0.5  13.23
  OJ  1.0  22.70
  OJ  2.0  26.06
  VC  0.5   7.98
  VC  1.0  16.77
  VC  2.0  26.14
')

来自ToothGrowth 数据集。

当x-axis作为连续变量时

我们可以用它绘制一个线图

ggplot(data=datn, aes(x=dose, y=length, group=supp, colour=supp)) +
    geom_line() +
    geom_point()

当x-axis作为分类变量时

首先,我们要将该变量转换为因子。

# 拷贝数据框并将它转换为因子
datn2 <- datn
datn2$dose <- factor(datn2$dose)
ggplot(data=datn2, aes(x=dose, y=length, group=supp, colour=supp)) +
    geom_line() +
    geom_point()

# 使用原始的数据框,但使用factor函数在绘图时转换
ggplot(data=datn, aes(x=factor(dose), y=length, group=supp, colour=supp)) +
    geom_line() +
    geom_point()

当连续值作为分类变量使用时,也可以绘制条形图。

ggplot(data=datn2, aes(x=dose, y=length, fill=supp)) +
    geom_bar(stat="identity", position=position_dodge())

ggplot(data=datn, aes(x=factor(dose), y=length, fill=supp)) +
    geom_bar(stat="identity", position=position_dodge())
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容