zoukankan      html  css  js  c++  java
  • ggplot2入门与进阶(下)

    出处:http://www.cellyse.com/how_to_use_gggplot2_part2/

    更多实战

    例一 Michaelis-Menten动力学方程

    这个例子中采用出自文献中的一组有关于浮萍氮摄取的数据,共2两个变量8个观测值,其中底物浓度与浮萍的氮取速率之间可以通过M-M动力学方程来进行描述。在这个例子中首先通过nls()根据M-M动力学方程进行模型拟合,然后用预测值进行了ggplot2绘图,主要采用了R里面的数学表示方法plotmath在图中展示了公式,并通过ggplot2种的theme对图像进行了修饰。需要注意的在geom_text()并不能直接使用expression,需要开启parse = TURE,且用字符串表示。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    conc <- c(2.856829, 5.005303, 7.519473, 22.101664, 27.769976, 39.198025, 45.483269, 203.784238)
    rate <- c(14.58342, 24.74123, 31.34551, 72.96985, 77.50099, 96.08794, 96.96624, 108.88374)
    L.minor <- data.frame(conc, rate)
    L.minor.m1 <- nls(rate ~ Vm * conc/(K + conc), data = L.minor, #采用M-M动力学方程
                      start = list(K = 20, Vm = 120), #初始值设置为K=20,Vm=120
                      trace = TRUE) #占线拟合过程
    #确定x轴范围并构建数据集
    min <- range(L.minor$conc)[1]
    max <- range(L.minor$conc)[2]
    line.data <- data.frame(conc = seq(min, max, length.out = 1000))
    #用模型预测数据构建数据集
    line.data$p.predict <- predict(L.minor.m1, newdata = line.data)
     
    require(ggplot2)
    M_Mfunction <- ggplot() +
      geom_point(aes(x = conc, y = rate), data = L.minor,
                 alpha = 0.5, size = 5, color = "red") +
      geom_line(aes(x = conc, y = p.predict), data = line.data,
                size = 1, color = "blue") +
      scale_x_continuous(
        name = expression(Substrate ~~ concentration(mmol ~~ m^3)),#采用expression来表示数学公式
        breaks = seq(0, 200, by = 25)) +
      scale_y_continuous(
        name = "Uptake rate (weight/h)",
        breaks = seq(0, 120, by = 10)) +
      geom_text(aes(x = 100, y = 60),
                label = "bolditalic(f(list(x, (list(K, V[m])))) == frac(V[m]%.%x, K+x))",
                #注意 geom_text中如果用expression()来进行表达,必须开启parse = TRUE
                #同时以字符串""的形式表示,不能使用expression
                parse = TRUE, 
                size = 5, family = "times"
                ) +
      theme_bw() +
      theme(
            axis.title.x=element_text(size=16),
            axis.title.y=element_text(size=16),
            axis.text.x=element_text(size=12),
            axis.text.y=element_text(size=12))


    例二 热图

    热图是一种极好的数据可视化方式,能够清楚的显示出多维数据之间的关联性和差异性,糗世界已经为我们展现了R里面所常用的heatmap,ggplot2和lattice3种热图绘制方式,当然随着R的不断进步,已经有多种包提供了更丰富和更简单的热图绘制方式,例如gplots中的heatmap.2,pheatmap,heatmap.plus等等。ggplot2进行热图的绘制也十分方便,热图的关键是聚类,两个可行的方案是对聚类结果进行排序和将聚类结果因子化后固定,通过结合plyr包,可以很方便的实现。这里采用一组来源于WHO国家数据来对热图的绘制进行,首先数据标准化和正态化后按Index的D(为各国的人口数据)进行排序,再将其因子化后固定,用geom_tile()进行热图的绘制,在ggplot2种已能通过scale_fill_gradient2在三种基本色进行渐变。

    数据下载

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    WHO<-read.csv("WHO.csv", header = TRUE)
    require(plyr)
    #按总人口数排列数据
    WHO<-arrange(WHO, desc(D))
    #将数据的名字转换为因子,并固定已拍好的country,
    #同理可以按照聚类的结果进行排列
    WHO<- transform(WHO, Country = factor(Country, levels = unique(Country)))
     
    require(reshape2)
    require(ggplot2)
    require(scales)
    require(grid)
    #melt数据
    m.WHO <- melt(WHO)
    #标准化,每排数据映射到按最小值和最大值映射到(0,1)区间
    m.WHO <- ddply(m.WHO, .(variable), transform, rescale = rescale(value))
    #标准化并正态化数据
    s.WHO <- ddply(m.WHO, .(variable), transform, rescale = scale(value))
    require(ggplot2)
    p<-ggplot(s.WHO, aes(variable, Country)) +
      #用tile来进行绘热力图
      geom_tile(aes(fill=rescale)) +
      scale_fill_gradient2(mid="black", high="red", low="green", name = "Intensity") +
      labs(x="Country", y="Index", face = "bold") +
      theme_bw() +
      theme(
        axis.title.x=element_text(size=16),
        axis.title.y=element_text(size=16),
        axis.text.x=element_text(size=12, colour="grey50"),
        axis.text.y=element_text(size=12, colour="grey50"),
        legend.title=element_text(size=14),
        legend.text=element_text(size=12),
        legend.key.size = unit(0.8, "cm"))#需要载入grid包来调整legend的大小

     

    例三 动态图

    相信很多人都被Hans Rosling在TED和BCC展现的动态散点图所惊艳到,这是一种多维数据展现方式,并成功的加入了时间这一维度,各路牛人都用不同的手段进行了实现,精彩的作品例如d3.js,和基于google charts API的googlevis。统计之都的魔王大人也用ggplot2结合animation包和ffmpeg进行了绘制。但ggplot2生成动态图比较简陋,主要的原理是一次输出多张按年份排列的图片,再将这些图片按顺序结合生成视频或动态图。在dataguru的课程上我使用循环并结合paste循环输出了如下的动态图,详细的代码请移步

     

    例四 火山图

    火山图是散点图的一种,能够快速的辨别出大型数据集重复变量之间的差异,具体的介绍可以参考wikiColin Gillespie的博客,下面的代码和图是使用ggplot2的实现方式。

    数据下载

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    require(ggplot2)
    ##change theme##
    old_theme <- theme_update(
      axis.ticks=element_line(colour="black"),
      panel.grid.major=element_blank(),
      panel.grid.minor=element_blank(),
      panel.background=element_blank(),
      axis.line=element_line(size=0.5)
    )
    ##Highlight genes that have an absolute fold change > 2 and a p-value < Bonferroni cut-off
    a <- read.table("flu.txt",header=TRUE,sep=" ",)
    P.Value <- c(a$P.Value)
    FC <- c(a$FC)
    df <- data.frame(P.Value, FC)
    df.G <- subset(df, log2(FC) < -1& P.Value < 0.05) #define Green
    df.G <- cbind(df.G, rep(1, nrow(df.G)))
    colnames(df.G)[3] <- "Color"
    df.B <- subset(df, (log2(FC) >= -1 & log2(FC) <= 1) | P.Value >= 0.05) #define Black
    df.B <- cbind(df.B, rep(2, nrow(df.B)))
    colnames(df.B)[3] <- "Color"
    df.R <- subset(df, log2(FC) > 1 & P.Value < 0.05) #define Red
    df.R <- cbind(df.R, rep(3, nrow(df.R)))
    colnames(df.R)[3] <- "Color"
    df.t <- rbind(df.G, df.B, df.R)
    df.t$Color <- as.factor(df.t$Color)
    ##Construct the plot object
    ggplot(data = df.t, aes(x = log2(FC), y = -log10(P.Value), color= Color )) +
      geom_point(alpha = 0.5, size = 1.75) +
      theme( legend.position = "none") +
      xlim(c(-5, 5)) + ylim(c(0, 20)) +
      scale_color_manual(values = c("green", "black", "red")) +
      labs(x=expression(log[2](FC)), y=expression( -log[10](P.Value))) +
      theme(axis.title.x=element_text(size=20),
            axis.text.x=element_text(size=15)) +
      theme(axis.title.y=element_text(size=20),
            axis.text.y=element_text(size=15))

     

     

    再说高质量图片输出

    绘图完成后最后一步便是图片输出,高质量的图片输出让人赏心悦目,而不正确的输出方式或者直接采用截图的方式从图形设备中截取,得到的图片往往是低劣的。一幅高质量的图片应当控制图片尺寸和字体大小,并对矢量图进行高质量渲染,即所谓的抗锯齿。R语言通过支持Cairo矢量图形处理的类库,可以创建高质量的矢量图形(PDF,PostScript,SVG) 和 位图(PNG,JPEG, TIFF),同时支持在后台程序中高质量渲染。在ggplot2我比较推荐的图片输出格式为经过Cairo包处理的PDF,因为PDF格式体积小,同时可以储存为其他任何格式,随后再将PDF储存为eps格式并在Photoshop中打开做最终的调整,例如调整比例、色彩空间和dpi(一般杂志和出版社要求dpi=300以上)等。额外需要注意的是ggplot2中的字体大小问题,在cookbook-r一书中指出,在ggplot2中绝大多数情况下,size的大小以mm记,详细的讨论也可以参考stackover的讨论,而在theme()中对element_text()里的size进行调整,此时的size是以磅值(points, pts)来进行表示。
    下面以3种ggplot2种常用的图片输出方式,输出一幅主标题为20pts,横纵坐标标题为15pts,长为80mm(3.15in),宽为60mm(2.36in)的图为例。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    require(ggplot2)
    require(Cairo)
    ggplot() +
      geom_text(aes(x = 16, y = 16), label = "ABC", size = 11.28) + #尺寸为11.28mm,即为32磅
      geom_text(aes(x = 16, y = 14.5), label = "ABC", size = 32) + #尺寸为32mm
      labs( x = "x axis", y = "y axis") +
      ylim( c(14, 16.5)) +
      xlim( c(15.75, 16.25)) +
      theme(
        axis.title.x = element_text(size = 32),#尺寸为32磅
        axis.title.y = element_text(size = 32))#尺寸为32磅
     
    x <- seq(-4,4, length.out = 1000)
    y <-dnorm(x)
    data <- data.frame(x, y)
     
    #用Cairo包输出
    require(Cairo)
    CairoPDF("plot1.pdf", 3.15, 3.15) #单位为英寸
    ggplot(data, aes(x = x, y = y)) + geom_line(size = 1) +
      theme_bw()
    dev.off() #关闭图像设备,同时储存图片
     
    plot2 <- ggplot(data, aes(x = x, y = y)) + geom_line(size = 1) +
      theme_bw()
    #用ggsave输出,默认即以用Cairo包进行抗锯齿处理
    ggsave("plot2.pdf", plot2, width = 3.15, height = 3.15)
     
    #RStudio输出
     
     
    更改字体

    更改默认字体或者采用中文输出图片是十分恼人的一件事情,好在我们还有各种拓展包和功能强大的Rstudio来实现。

     

    用extrafont输出英文字体

    extrafont包能够直接调用字体文件,再通过Ghostscript(需要安装)将写入的字体插入生成的PDF中,具体代码可参考了作者说明

    好玩的showtext

    邱怡轩大神写了一个好玩的showtext,确实好好玩~

    简单易用的RStudio输出

    最简单实用的输出方法还是使用RStudio输出,直接调用系统字体(我的是win7,mac和linux下还没有试过)并输出即可

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #showtext
    require(showtext)
    require(ggplot2)
    require(Cairo)
    font.add("BlackoakStd", "C://Windows//Fonts//BlackoakStd.otf")
    font.add("BrushScriptStd", "C://Windows//Fonts//BrushScriptStd.otf")
    font.add("times", "C://Windows//Fonts//times.ttf")
    font.add("STHUPO", "C://Windows//Fonts//STHUPO.ttf")
    CairoPDF("showtext_output", 8, 8)
    showtext.begin()
    ggplot() +
      geom_text(aes(x = 16, y = 16.25), label = "Blackoak Std", size = 8,
                family = "BlackoakStd") +
      geom_text(aes(x = 16, y = 16), label ="Brush Script Std", size = 16,
                family = "BrushScriptStd") +
      geom_text(aes(x = 16, y = 15.75), label = "Times New Roman", size = 16,
                family = "times") +
      geom_text(aes(x = 16, y = 15.50), label = "华文琥珀", size = 16,
                family = "STHUPO") +
      ylim(c(15.25, 16.50)) +
      labs(x = "", y = "") +
      theme_bw() #在用RStudio输出

  • 相关阅读:
    2021,6,10 xjzx 模拟考试
    平衡树(二)——Treap
    AtCoder Beginner Contest 204 A-E简要题解
    POJ 2311 Cutting Game 题解
    Codeforces 990G GCD Counting 题解
    NOI2021 SDPTT D2T1 我已经完全理解了 DFS 序线段树 题解
    第三届山东省青少年创意编程与智能设计大赛总结
    Luogu P6042 「ACOI2020」学园祭 题解
    联合省选2021 游记
    Codeforces 1498E Two Houses 题解 —— 如何用结论吊打标算
  • 原文地址:https://www.cnblogs.com/lantingg/p/7999257.html
Copyright © 2011-2022 走看看