zoukankan      html  css  js  c++  java
  • (数据科学学习手札38)ggplot2基本图形简述

    一、简介

      上一篇中我们介绍了ggplot2的基本语法规则,为了生成各种复杂的叠加图层,需要了解ggplot2中一些基本的几何图形的构造规则,本文便就常见的基础几何图形进行说明;

    二、各基础图形

    2.1 abline()、hline()与vline()

      在R的基础绘图系统中我们可以在已绘制的图床上通过abline来添加线条,在ggplot2中当然也有类似的方法:

    geom_abline():

      我们主要使用两个参数控制线条的位置,slope控制斜率,intercept控制截距,下面是一个简单的例子,我们在散点图层上叠加截距为20,斜率为2的直线:

    library(ggplot2)
    
    p <- ggplot(mtcars, aes(wt, mpg)) + 
      geom_point() +
      geom_abline(intercept = 20,slope = 2)
    p

    geom_vline():

      如果你想添加的直线垂直于x轴,则可以使用geom_vline()来快捷地添加垂直线条,xintercept传入的参数即为线条在x轴上的位置,若传入向量则可同时添加多条线条:

    library(ggplot2)
    
    p <- ggplot(mtcars, aes(wt, mpg)) + 
      geom_point() +
      geom_vline(xintercept = 5)
    p

    p <- ggplot(mtcars, aes(wt, mpg)) + 
      geom_point() +
      geom_vline(xintercept = 1:5)
    p

    geom_hline():

      同样的,我们通过在geom_hline()中传入参数yintercept来绘制垂直于y轴的线条:

    p <- ggplot(mtcars, aes(wt, mpg)) + 
      geom_point() +
      geom_hline(yintercept = 20)
    p

    p <- ggplot(mtcars, aes(wt, mpg)) + 
      geom_point() +
      geom_hline(yintercept = 15:25)
    p

     2.2 area()

       面积图也是一种很常用的图,多用于表现某些水平或比例类指标随时间的变化情况,下面是一个朴素的例子,以huron湖水水平变化数据为例:

    library(ggplot2)
    
    p <- ggplot(huron,aes(x=year,y=level))+
      geom_area(fill='springgreen')
    p

      实际上面积图最有表现力的类型是堆积面积图,下面以美国5个消费指标上5个年份的数据为例绘制堆积面积图:

    library(ggplot2)
    library(reshape2)
    
    #将原数据转置以处理成行对应一个年份的形式
    data <- data.frame(t(USPersonalExpenditure))
    #添加年份变量
    data$year <- as.numeric(row.names(data))
    #利用reshape2中的melt函数按照year列将原数据集伸展为“年份、变量名、对应数值”的形式
    data <- melt(data, id='year')
    
    h <- ggplot(data, aes(x=year, y=value))+
      geom_area(aes(fill=variable),position = 'fill')+
      theme(legend.position = 'bottom')+
      labs(title='堆积面积图')+
      theme(plot.title = element_text(hjust=0.5))
    h

      这样得到的图就比较具有美感和表现力,当然我们更改position参数也可以得到真实的水平逐年变化情况:

    h <- ggplot(data, aes(x=year, y=value))+
      geom_area(aes(fill=variable),position = 'identity')+
      theme(legend.position = 'bottom')+
      labs(title='堆积面积图')+
      theme(plot.title = element_text(hjust=0.5))
    h

     2.3 bar()

      基础的条形图我们前面一篇中已经涉及到了,所以这里我们只与上述的堆积面积图进行对比,这里注意,geom_bar()默认的统计变换为count,即计算频数,我们这里想展示真实数值需要将geom_bar()中的stat设置为'identity',即不做任何变换:

    library(ggplot2)
    library(reshape2)
    
    data <- data.frame(t(USPersonalExpenditure))
    data$year <- row.names(data)
    data <- melt(data, id='year')
    
    p <- ggplot(data, aes(x=year,y=value))+
      geom_bar(aes(fill=factor(variable)),stat = 'identity')+
      labs(title='消费水平')+
      theme(plot.title=element_text(hjust=0.5))
    p

      可以看出这时我们的堆叠条形图便而可以看作离散的堆积面积图;

    2.4 bin2d()

      二维热图也是一种非常实用的图像,我们可以用来一览数据的某两个变量上的指标分布情况:

    library(ggplot2)
    
    d <- ggplot(diamonds, aes(x, y))+
      geom_bin2d()+
      labs(title='钻石长宽分布')+
      theme(plot.title=element_text(hjust=0.5))
    d

      我们还可以利用bin2d()来直观的了解数据集的缺失情况:

    library(ggplot2)
    library(reshape2)
    
    #载入数据
    data <- airquality
    #统计缺失值位置并保存为矩阵
    na.count <- is.na(data[,-6])
    
    #用1表示缺失,0表示未缺失
    na.count[na.count == T] <- 1
    na.count[na.count == F] <- 0
    
    #将Day按列与na.count拼接并转为数据框
    na.count <- data.frame(cbind(na.count,data[,6]))
    names(na.count) <- names(airquality)
    #利用melt以Day为b
    na.count <- melt(na.count,id='Day')
    #绘制数据集缺失情况概括图,以变量名为分面依据
    p <- ggplot(na.count,aes(x=Day,y=value))+
      geom_bin2d()+
      facet_grid(facets = .~variable)
    p

    2.5 density()与density2d()

      很多时候当我们获取的数据集样本数量足够时,通常我们可以绘制密度估计图来大致描述数据集数据的分布,ggplot2中当然提供了这类方法,我们先从一维的说起:
    geom_density():

      和R基本绘图系统中的密度曲线绘制方法很接近:

    library(ggplot2)
    
    data <- data.frame(matrix(rnorm(200),nrow=100))
    v <- ggplot(data, aes(x=X1))+
      geom_density(alpha=0.3,fill='springgreen',colour='springgreen')
    v

    geom_density2d():

      和density()类似,只是我们可以通过density2d来绘制二维变量的概率密度分布:

    v <- ggplot(data, aes(X1, X2))+
      geom_point()+
      stat_density2d(aes(colour=..level..))
    v

      也可以不绘制等高线,将..density..作为fill的传入参数,注意这里一定要设置contour为F:

    # 密度图函数,通过fill设置填充颜色数据为密度,geom设置绘制栅格图
    p <- ggplot(data, aes(x = X1, y = X2)) +
      stat_density2d(aes(fill = ..density..), geom = "raster", contour = F)
    p

      或是在透明度alpha上动手脚:

    # 密度图函数:alpha设置填充透明度数据为密度,geom设置绘制栅格图
    p <- ggplot(data, aes(x = X1, y = X2)) +
      geom_point() +
      stat_density2d(aes(alpha = ..density..), geom = "raster", contour = FALSE)
    p

    2.6 boxplot()

      在统计学描述数据分布的图形中,箱线图是非常有代表性的,它通过图形表现五数概括的情况,在数据基本的描述性统计中具有重要意义,而ggplot2中必然可以绘制箱线图,而且可以绘制得非常精美,下面先看一个最朴素的分组箱线图形式:

    p <- ggplot(mpg, aes(class, hwy)) +
      geom_boxplot()
    p

    我们为其赋以分组依据以配上颜色:

    p <- ggplot(mpg, aes(class, hwy, fill=factor(class)))
    p + geom_boxplot()

    为我们的填充设置透明度,并将边框也赋以对应的颜色:

    p <- ggplot(mpg, aes(class, hwy, fill=factor(class), colour=factor(class)))+
      geom_boxplot(alpha=0.55)
    p

      还可以将散点图与箱线图结合起来(这里施加jitter随机扰动以组织样本点重合):

    p <- ggplot(mpg, aes(class, hwy, fill=factor(class), colour=factor(class)))+
      geom_boxplot(alpha=0.55)+
      geom_point(position = 'jitter')
    p

    2.7 histogram()

      关于直方图,因为前面也说过,这里就举几个由朴素的直方图扩展开的示例:

    library(ggplot2)
    
    
    p <- ggplot(diamonds, aes(carat)) +
      geom_histogram()
    p

    p <- ggplot(diamonds, aes(carat,fill=cut)) +
      geom_histogram()
    p

    p <- ggplot(diamonds, aes(carat, fill=cut)) +
      geom_histogram()+
      facet_grid(facets = .~cut)
    p

    2.8 curve()与segment()

      有时候我们需要在已绘制的图形中添加线段、曲线、小箭头之类的注解,这时候就可以用到ggplot2中的geom_curve()与geom_segment(),他们的主要参数类似,需要在aes()中定义起点坐标x、y,以及终点坐标xend、yend,如需要线段或曲线上带有小箭头,则额外定义参数arrow即可,箭头方向由之前的起点终点决定:

    data <- data.frame(x=c(1,2,3,4),y=c(1,2,3,4))
    
    p <- ggplot(data,aes(x,y))+
      geom_point()
    p
    
    p + geom_curve(data=data,aes(x=x[1],y=y[1],xend=x[4],yend=y[4],colour='曲线'))

    在原有图形基础上添加线段并带上小箭头:

    p + geom_curve(data=data,aes(x=x[1],y=y[1],xend=x[4],yend=y[4],colour='曲线'))+
      geom_segment(data=data,aes(x=x[2],y=y[2],xend=x[3],yend=y[3],colour='直线'),
                   arrow = arrow(length = unit(0.02, 'npc')))

    2.9 text()与label()

      有些时候我们需要在已绘制的图形上添加文本类标签,这种时候就需要用到text()和label()了,下面以不同的示例来说明其常见用法:

    用对应每一个样本的文本标签代替散点

    p <- ggplot(mtcars, aes(wt, mpg, label = rownames(mtcars)))
    
    p + geom_text()

    对出现标签遮挡的情况进行抹除(不建议使用):

    p + geom_text(check_overlap = TRUE)

    使用别致的标签:

    p + geom_label()

    改变文本标签的大小:

    p + geom_text(size = 10)

    调整文字标签位置:

    p + geom_point() + geom_text(hjust = 0, nudge_x = 0.05)

    调整文字标签位置:

    p + geom_point() + geom_text(vjust = 0, nudge_y = 0.5)

    调整文本标签位置:

    p + geom_point() + geom_text(angle = 45)

    更精致的标签类型:

    p + geom_label(aes(fill = factor(cyl)), colour = "white", fontface = "bold")

    在图床指定位置添加文本标签:

    df <- data.frame(
      x = c(1, 1, 2, 2, 1.5),
      y = c(1, 2, 1, 2, 1.5),
      text = c("bottom-left", "bottom-right", "top-left", "top-right", "center")
    )
    ggplot(df, aes(x, y)) +
      geom_text(aes(label = text))

    可以看出,落入四角的标签因为其中心对应坐标点,导致部分内容伸出边界,这里我们令vjust = "inward", hjust = "inward"使得它自适应的调整位置以显示全部信息:

    ggplot(df, aes(x, y)) +
      geom_text(aes(label = text), vjust = "inward", hjust = "inward")

    2.10 violin()

      小提琴图是一种功能和箱线图类似,但增加了核密度估计功能的图形,且更为美观,ggplot2可以绘制出与seaborn中的小提琴图同样优美的图形,因为涉及的内容比较复杂,我准备在之后单独开一篇来介绍,下面仅展示一张简单的小提琴图:

    library(ggplot2)
    
    data <- mtcars
    
    p <- ggplot(data, aes(factor(cyl), mpg))+
      geom_violin(aes(fill = cyl,colour=cyl))
    p

      以上就是ggplot2中常规图形的简单介绍,其中比较重要且比较复杂的几种将会在之后单独开文章详细介绍,如有笔误,望指出。

  • 相关阅读:
    堆栈学习
    需要阅读的书籍
    Rust Book Lang Ch.19 Fully Qualified Syntax, Supertraits, Newtype Pattern, type aliases, never type, dynamic sized type
    Rust Lang Book Ch.19 Placeholder type, Default generic type parameter, operator overloading
    Rust Lang Book Ch.19 Unsafe
    Rust Lang Book Ch.18 Patterns and Matching
    Rust Lang Book Ch.17 OOP
    Rust Lang Book Ch.16 Concurrency
    Rust Lang Book Ch.15 Smart Pointers
    HDU3966-Aragorn's Story-树链剖分-点权
  • 原文地址:https://www.cnblogs.com/feffery/p/9097704.html
Copyright © 2011-2022 走看看