首页 文章

在ggplot2中使用边缘直方图的散点图

提问于
浏览
117

有没有办法用边缘直方图创建散点图,就像在 ggplot2 中的下面的示例中一样?在Matlab中,它是 scatterhist() 函数,并且R也存在等价物 . 但是,我还没有看到ggplot2 .

scatterplot with marginal histograms

我开始尝试创建单个图形但不知道如何正确排列它们 .

require(ggplot2)
 x<-rnorm(300)
 y<-rt(300,df=2)
 xy<-data.frame(x,y)
     xhist <- qplot(x, geom="histogram") + scale_x_continuous(limits=c(min(x),max(x))) + opts(axis.text.x = theme_blank(), axis.title.x=theme_blank(), axis.ticks = theme_blank(), aspect.ratio = 5/16, axis.text.y = theme_blank(), axis.title.y=theme_blank(), background.colour="white")
     yhist <- qplot(y, geom="histogram") + coord_flip() + opts(background.fill = "white", background.color ="black")

     yhist <- yhist + scale_x_continuous(limits=c(min(x),max(x))) + opts(axis.text.x = theme_blank(), axis.title.x=theme_blank(), axis.ticks = theme_blank(), aspect.ratio = 16/5, axis.text.y = theme_blank(), axis.title.y=theme_blank() )


     scatter <- qplot(x,y, data=xy)  + scale_x_continuous(limits=c(min(x),max(x))) + scale_y_continuous(limits=c(min(y),max(y)))
none <- qplot(x,y, data=xy) + geom_blank()

并使用发布的功能here安排它们 . 但长话短说:有没有办法创建这些图表?

8 回答

  • 27

    gridExtra 包应该在这里工作 . 首先制作每个ggplot对象:

    hist_top <- ggplot()+geom_histogram(aes(rnorm(100)))
    empty <- ggplot()+geom_point(aes(1,1), colour="white")+
             theme(axis.ticks=element_blank(), 
                   panel.background=element_blank(), 
                   axis.text.x=element_blank(), axis.text.y=element_blank(),           
                   axis.title.x=element_blank(), axis.title.y=element_blank())
    
    scatter <- ggplot()+geom_point(aes(rnorm(100), rnorm(100)))
    hist_right <- ggplot()+geom_histogram(aes(rnorm(100)))+coord_flip()
    

    然后使用grid.arrange函数:

    grid.arrange(hist_top, empty, scatter, hist_right, ncol=2, nrow=2, widths=c(4, 1), heights=c(1, 4))
    

    plot

  • 43

    由于在比较不同的群体时,对于这种情节没有令人满意的解决方案,我写了一个function来做到这一点 .

    它适用于分组和未分组数据,并接受其他图形参数:

    marginal_plot(x = iris$Sepal.Width, y = iris$Sepal.Length)
    

    enter image description here

    marginal_plot(x = Sepal.Width, y = Sepal.Length, group = Species, data = iris, bw = "nrd", lm_formula = NULL, xlab = "Sepal width", ylab = "Sepal length", pch = 15, cex = 0.5)
    

    enter image description here

  • 106

    在分布边际指标的一般精神中,只是一个非常小的变化BondedDust's answer .

    Edward Tufte将地毯图的使用称为'dot-dash plot',并且在VDQI中有一个使用轴线指示每个变量范围的示例 . 在我的示例中,轴标签和网格线也指示数据的分布 . 标签位于Tukey's five number summary(最小,下铰链,中间,上铰链,最大)的值,给出了每个变量的传播的快速印象 .

    因此,这五个数字是箱线图的数字表示 . 这有点棘手,因为不均匀间隔的网格线表明轴具有非线性标度(在此示例中它们是线性的) . 也许最好省略网格线或强制它们在常规位置,并让标签显示五个数字摘要 .

    x<-rnorm(300)
    y<-rt(300,df=10)
    xy<-data.frame(x,y)
    
    require(ggplot2); require(grid)
    # make the basic plot object
    ggplot(xy, aes(x, y)) +        
      # set the locations of the x-axis labels as Tukey's five numbers   
      scale_x_continuous(limit=c(min(x), max(x)), 
                         breaks=round(fivenum(x),1)) +     
      # ditto for y-axis labels 
      scale_y_continuous(limit=c(min(y), max(y)),
                         breaks=round(fivenum(y),1)) +     
      # specify points
      geom_point() +
      # specify that we want the rug plot
      geom_rug(size=0.1) +   
      # improve the data/ink ratio
      theme_set(theme_minimal(base_size = 18))
    

    enter image description here

  • 8

    这不是一个完全响应的答案,但它非常简单 . 它说明了显示边际密度的另一种方法,以及如何将alpha级别用于支持透明度的图形输出:

    scatter <- qplot(x,y, data=xy)  + 
             scale_x_continuous(limits=c(min(x),max(x))) + 
             scale_y_continuous(limits=c(min(y),max(y))) + 
             geom_rug(col=rgb(.5,0,0,alpha=.2))
    scatter
    

    enter image description here

  • 74

    我发现该软件包( ggpubr )似乎对此问题非常有效,并且它考虑了显示数据的几种可能性 .

    包的链接是here,在this link中你会找到一个很好的教程来使用它 . 为了完整起见,我附上了我复制的一个例子 .

    我首先安装了包(它需要 devtools

    if(!require(devtools)) install.packages("devtools")
    devtools::install_github("kassambara/ggpubr")
    

    对于显示不同组的不同直方图的特定示例,它与 ggExtra 有关:“ ggExtra 的一个限制是它无法处理散点图和边缘图中的多个组 . 在下面的R代码中,我们使用 cowplot 包提供解决方案 . “在我的情况下,我不得不安装后一个包:

    install.packages("cowplot")
    

    我按照这段代码:

    # Scatter plot colored by groups ("Species")
    sp <- ggscatter(iris, x = "Sepal.Length", y = "Sepal.Width",
                color = "Species", palette = "jco",
                size = 3, alpha = 0.6)+
    border()                                         
    # Marginal density plot of x (top panel) and y (right panel)
    xplot <- ggdensity(iris, "Sepal.Length", fill = "Species",
                   palette = "jco")
    yplot <- ggdensity(iris, "Sepal.Width", fill = "Species", 
                   palette = "jco")+
    rotate()
    # Cleaning the plots
    sp <- sp + rremove("legend")
    yplot <- yplot + clean_theme() + rremove("legend") 
    xplot <- xplot + clean_theme() + rremove("legend")
    # Arranging the plot using cowplot
    library(cowplot)
    plot_grid(xplot, NULL, sp, yplot, ncol = 2, align = "hv", 
          rel_widths = c(2, 1), rel_heights = c(1, 2))
    

    这对我很好:

    Iris set marginal histograms scatterplot

    enter image description here

  • 83

    一个补充,只是为了节省一些人在我们之后这样做的搜索时间 .

    传说,轴标签,轴文本,刻度使得情节相互偏离,因此您的情节将看起来丑陋且不一致 .

    您可以使用其中一些主题设置来更正此问题,

    +theme(legend.position = "none",          
           axis.title.x = element_blank(),
           axis.title.y = element_blank(),
           axis.text.x = element_blank(),
           axis.text.y = element_blank(), 
           plot.margin = unit(c(3,-5.5,4,3), "mm"))
    

    和对齐尺度,

    +scale_x_continuous(breaks = 0:6,
                        limits = c(0,6),
                        expand = c(.05,.05))
    

    所以结果看起来还不错:

    an example

  • 3

    这可能有点晚了,但我决定为此创建一个包( ggExtra ),因为它涉及一些代码并且编写起来可能很乏味 . 该软件包还试图解决一些常见问题,例如确保即使有 Headers 或文本被放大,这些图仍将是彼此内联的 .

    基本思想类似于这里给出的答案,但它有点超出了这个范围 . 以下是如何将边缘直方图添加到1000个点的随机集中的示例 . 希望这可以使将来更容易添加直方图/密度图 .

    Link to ggExtra package

    library(ggplot2)
    df <- data.frame(x = rnorm(1000, 50, 10), y = rnorm(1000, 50, 10))
    p <- ggplot(df, aes(x, y)) + geom_point() + theme_classic()
    ggExtra::ggMarginal(p, type = "histogram")
    

    enter image description here

  • 1

    您可以使用ggstatsplot轻松创建具有边缘直方图的有吸引力的散点图(它也适合并描述模型):

    data(iris)
    
    library(ggstatsplot)
    
    ggscatterstats(
      data = iris,                                          
      x = Sepal.Length,                                                  
      y = Sepal.Width,
      xlab = "Sepal Length",
      ylab = "Sepal Width",
      marginal = TRUE,
      marginal.type = "histogram",
      centrality.para = "mean",
      margins = "both",
      title = "Relationship between Sepal Length and Sepal Width",
      messages = FALSE
    )
    

    enter image description here

    或者更具吸引力(默认情况下)ggpubr

    devtools::install_github("kassambara/ggpubr")
    library(ggpubr)
    
    ggscatterhist(
      iris, x = "Sepal.Length", y = "Sepal.Width",
      color = "Species", # comment out this and last line to remove the split by species
      margin.plot = "histogram", # I'd suggest removing this line to get density plots
      margin.params = list(fill = "Species", color = "black", size = 0.2)
    )
    

    enter image description here

    UPDATE:

    正如@aickley所建议的那样,我使用了开发版来创建情节 .

相关问题