美文网首页收入即学习ggplot2生信
[ggplot2]跟着Y叔学ggplot2(一)

[ggplot2]跟着Y叔学ggplot2(一)

作者: 巩翔宇Ibrahimovic | 来源:发表于2020-03-04 19:52 被阅读0次

    1.数据和映射

    require(ggplot2)
    data("diamonds")
    set.seed(42)
    small <- diamonds[sample(nrow(diamonds),1000),]
    head(small)
    
    

    把数据中的变量映射到图形属性上

    p <- ggplot(data = small, mapping = aes(x = carat, y = price))
    

    映射完成后,要告诉ggplot2展示出什么样的几何图形,以散点图为例

    p+geom_point()
    

    如果想将切工(cut)映射到图形属性[也就是再添加一列数据],则是如下:

    p <- ggplot(data=small, mapping=aes(x=carat, y=price, shape=cut))
    p+geom_point()
    

    如果想将钻石的颜色映射到颜色属性

    p <- ggplot(data=small, mapping=aes(x=carat, y=price, shape=cut, colour=color))
    p+geom_point()
    

    2.几何对象(Geometric)
    在上面的例子中,各种属性映射由ggplot函数执行,只需要加一个图层,使用geom_point()告诉ggplot要画散点,于是所有的属性都映射到散点上。
    geom_point()完成的就是几何对象的映射,ggplot2提供了各种几何对象映射,如geom_histogram用于直方图,geom_bar用于画柱状图,geom_boxplot用于画箱式图等等。
    属性也可以加在几何对象映射上

    p <- ggplot(small)
    p+geom_point(aes(x=carat, y=price, shape=cut, colour=color))
    

    ggplot2支持图层,通常把不同的图层中共用的映射提供给ggplot函数,而某一几何对象才需要的映射参数提供给geom_xxx函数.
    2.1直方图的绘制 提供一个x变量,画出数据分布

    ggplot(small)+geom_histogram(aes(x=price))
    

    同样可以根据另外的变量给它填充颜色,比如按不同的切工:

    ggplot(small)+geom_histogram(aes(x=price, fill=cut))
    

    也可以将其分开,side-by-side地画直方图。positon,位置调整,可以是字符串,也可以是调用位置调整函数的结果

    ggplot(small)+geom_histogram(aes(x=price, fill=cut), position="dodge")
    

    还可以使用position=”fill”,按照相对比例来画。

    ggplot(small)+geom_histogram(aes(x=price, fill=cut), position="fill")
    

    2.2 柱状图绘制
    柱状图非常适合于画分类变量。在这里以透明度(clarity)变量为例。按照不同透明度的钻石的数目画柱状图。

    ggplot(small)+geom_bar(aes(x=clarity))
    

    柱状图两个要素,一个是分类变量,一个是数目,也就是柱子的高度。数目在这里不用提供,因为ggplot2会通过x变量计算各个分类的数目。

    当然你想提供也是可以的,通过stat参数,可以让geom_bar按指定高度画图,比如以下代码:

    ggplot()+geom_bar(aes(x=c(LETTERS[1:3]),y=1:3), stat="identity")
    

    柱状图和直方图是很像的,直方图把连续型的数据按照一个个等长的分区(bin)来切分,然后计数,画柱状图。而柱状图是分类数据,按类别计数。我们可以用前面直方图的参数来画side-by-side的柱状图,填充颜色或者按比例画图,它们是高度一致的。

    柱状图是用来表示计数数据的,但在生物界却被经常拿来表示均值,加上误差来表示数据分布,这可以通常图层来实现,我将在图层一节中给出实例。
    2.3密度函数图
    说到直方图,就不得不说密度函数图,数据和映射和直方图是一样的,唯一不同的是几何对象,geom_histogram告诉ggplot要画直方图,而geom_density则说我们要画密度函数图,在我们熟悉前面语法的情况下,很容易画出:colour参数指定的是曲线的颜色,而fill是往曲线下面填充颜色。

    ggplot(small)+geom_density(aes(x=price, colour=cut))
    ggplot(small)+geom_density(aes(x=price,fill=clarity))
    

    2.4箱线图
    数据量比较大的时候,用直方图和密度函数图是表示数据分布的好方法,而在数据量较少的时候,比如很多的生物实验,很多时候大家都是使用柱状图+errorbar的形式来表示,不过这种方法的信息量非常低,被Nature Methods吐槽,这种情况推荐使用boxplot。

    ggplot(small)+geom_boxplot(aes(x=cut, y=price,fill=color))
    

    ggplot2提供了很多的geom_xxx函数,可以满足我们对各种图形绘制的需求。

    geom_abline     geom_area   
    geom_bar        geom_bin2d
    geom_blank      geom_boxplot    
    geom_contour    geom_crossbar
    geom_density    geom_density2d  
    geom_dotplot    geom_errorbar
    geom_errorbarh  geom_freqpoly   
    geom_hex        geom_histogram
    geom_hline      geom_jitter     
    geom_line       geom_linerange
    geom_map        geom_path   
    geom_point      geom_pointrange
    geom_polygon    geom_quantile   
    geom_raster     geom_rect
    geom_ribbon     geom_rug    
    geom_segment    geom_smooth
    geom_step       geom_text   
    geom_tile       geom_violin
    geom_vline
    

    3.标尺
    前面我们已经看到了,画图就是在做映射,不管是映射到不同的几何对象上,还是映射各种图形属性。这一小节介绍标尺,在对图形属性进行映射之后,使用标尺可以控制这些属性的显示方式,比如坐标刻度,可能通过标尺,将坐标进行对数变换;比如颜色属性,也可以通过标尺,进行改变。将Y轴坐标进行log10变换,再自己定义颜色为彩虹色。

    ggplot(small)+geom_point(aes(x=carat, y=price, shape=cut, colour=color))+scale_y_log10()+scale_colour_manual(values=rainbow(7))
    

    4.统计变换(statistics)
    统计变换对原始数据进行某种计算,然后在图上表示出来,例如对散点图上加一条回归线。加入scale_y_log10(),使用坐标变换,数据并不会被修剪,只是将数据放大或缩小到指定范围。

    ggplot(small, aes(x=carat, y=price))+geom_point()+scale_y_log10()+stat_smooth()
    

    **5.坐标系统(Coordinante)
    坐标系统控制坐标轴,可以进行变换,例如XY轴翻转,笛卡尔坐标和极坐标转换,以满足我们的各种需求。
    坐标轴翻转由coord_flip()实现

    ggplot(small)+geom_bar(aes(x=cut, fill=cut))+coord_flip()
    

    而转换成极坐标可以由coord_polar()实现:

    ggplot(small)+geom_bar(aes(x=factor(1), fill=cut))+coord_polar(theta="y")
    

    饼图实际上就是柱状图,只不过是使用极坐标而已,柱状图的高度,对应于饼图的弧度,饼图并不推荐,因为人类的眼睛比较弧度的能力比不上比较高度(柱状图)
    还可以画靶心图:(为何这里的靶点图中间缺了一部分)

    ggplot(small)+geom_bar(aes(x=factor(1), fill=cut))+coord_polar()
    

    风玫瑰图(不知道这里和靶点图最主要区别在哪)

    ggplot(small)+geom_bar(aes(x=clarity, fill=cut))+coord_polar()
    

    6.图层(layer)
    ggplot的牛B之处在于使用+号来叠加图层,这堪称是泛型编程的典范。在前面散点图上,我们已经见识过,加上了一个回归线拟合的图层。做为图层的一个很好的例子是蝙蝠侠logo,batman
    logo由6个函数组成,在下面的例子中,我先画第一个函数,之后再加一个图层画第二个函数,不断重复这一过程,直到六个函数全部画好。
    7.分面(facet)
    分面可以让我们按照某种给定的条件,对数据进行分组,然后分别画图。
    在统计变换一节中,提到如果按切工分组作回归线,显然图会很乱,有了分面功能,我们可以分别作图。

    ggplot(small, aes(x=carat, y=price))+geom_point(aes(colour=cut))+scale_y_log10() +facet_wrap(~cut)+stat_smooth()
    

    8.主题(theme)
    通过ggplot画图之后,我们可能还需要对图进行定制,像title, xlab,
    ylab这些高频需要用到的,自不用说,ggplot2提供了ggtitle(),
    xlab()和ylab()来实现。 比如:

    p <- ggplot(small)+geom_boxplot(aes(x=cut, y=price,fill=color))
    p + ggtitle("Price vs Cut")+xlab("Cut")+ylab("Price")
    

    但是这个远远满足不了需求,我们需要改变字体,字体大小,坐标轴,背景等各种元素,这需要通过theme()函数来完成。
    ggplot2提供一些已经写好的主题,比如theme_grey()为默认主题,我经常用的theme_bw()为白色背景的主题,还有theme_classic()主题,和R的基础画图函数较像。

    别外ggthemes包提供了一些主题可供使用,包括:

    theme_economist theme_economist_white
    theme_wsj       theme_excel
    theme_few       theme_foundation
    theme_igray     theme_solarized
    theme_stata     theme_tufte
    
    require(ggthemes)
    p + theme_wsj()
    

    9.二维密度图
    在这个文档里,为了作图方便,我们使用diamonds数据集的一个子集,如果使用全集,数据量太大,画出来散点就糊了,这种情况可以使用二维密度力来呈现。

    ggplot(diamonds, aes(carat, price))+ stat_density2d(aes(fill = ..level..), geom="polygon")+ scale_fill_continuous(high='darkred',low='darkgreen')
    

    最后以生物界中常用的柱状图+误差图为实例,展示ggplot2非常灵活的图层。

    Normal <- c(0.83, 0.79, 0.99, 0.69)
    Cancer <- c(0.56, 0.56, 0.64, 0.52)
    m <- c(mean(Normal), mean(Cancer))
    s <- c(sd(Normal), sd(Cancer))
    d <- data.frame(V=c("Normal", "Cancer"), mean=m, sd=s)
    d$V <- factor(d$V, levels=c("Normal", "Cancer"))
    
    p <- ggplot(d, aes(V, mean, fill=V, width=.5))
    p <- p+geom_errorbar(aes(ymin=mean, ymax=mean+sd, width=.2), 
                         position=position_dodge(width=.8))
    p <- p + geom_bar(stat="identity", position=position_dodge(width=.8), colour="black")
    p <- p + scale_fill_manual(values=c("grey80", "white"))
    p <- p + theme_bw() +theme(legend.position="none") + xlab("") + ylab("")
    p <- p + theme(axis.text.x = element_text(face="bold", size=12), 
                   axis.text.y = element_text(face="bold", size=12))
    p <- p+scale_y_continuous(expand=c(0,0), limits=c(0, 1.2), breaks=seq(0, 1.2, by=.2))
    p <- p+geom_segment(aes(x=1, y=.98, xend=1, yend=1.1))
    p <- p+geom_segment(aes(x=2, y=.65, xend=2, yend=1.1))
    p <- p+geom_segment(aes(x=1, y=1.1, xend=2, yend=1.1))
    p <- p + annotate("text", x=1.5, y=1.08, label="*")
    print(p)
    

    参考链接:
    https://mp.weixin.qq.com/s?__biz=MzI5NjUyNzkxMg==&mid=2247483941&idx=1&sn=bb352b5d74797715a9759f64765e49f6&scene=21#wechat_redirect

    相关文章

      网友评论

        本文标题:[ggplot2]跟着Y叔学ggplot2(一)

        本文链接:https://www.haomeiwen.com/subject/eqjilhtx.html