从 R 中的同一变量绘制边际直方图(作为因子)和散点图(作为数字)
Plotting marginal histograms (as factors) and scatterplot (as numeric) from the same variable in R
我正在尝试创建一个带有边际直方图的散点图,如 this question 中所示。
我的数据是两个(数字)变量,它们共享七个离散(有点)对数间隔的级别。
我在 ggExtra
包中的 ggMarginal
的帮助下成功完成了这项工作,但是我对结果不满意,因为使用与散点图,事情不排队。
如下所示,直方图条偏向数据点本身的右侧或左侧。
library(ggMarginal)
library(ggplot2)
x <- rep(log10(c(1,2,3,4,5,6,7)), times=c(3,7,12,18,12,7,3))
y <- rep(log10(c(1,2,3,4,5,6,7)), times=c(3,1,13,28,13,1,3))
d <- data.frame("x" = x,"y" = y)
p1 <- ggMarginal(ggplot(d, aes(x,y)) + geom_point() + theme_bw(), type = "histogram")
一个可能的解决方案是将直方图中使用的变量更改为因子,以便它们与散点图轴很好地对齐。
这在使用 ggplot
:
创建直方图时效果很好
p2 <- ggplot(data.frame(lapply(d, as.factor)), aes(x = x)) + geom_histogram()
然而,当我尝试使用 ggMarginal
执行此操作时,我没有得到想要的结果 - ggMarginal
直方图似乎仍在将我的变量视为数字。
p3 <- ggMarginal(ggplot(d, aes(x,y)) + geom_point() + theme_bw(),
x = as.factor(x), y = as.factor(y), type = "histogram")
如何确保直方图条形位于数据点的中心?
我绝对愿意接受不涉及使用 ggMarginal
的答案。
如果你愿意尝试 baseplotting,这里有一个函数:
plots$scatterWithHists <- function(x, y, histCols=c("lightblue","lightblue"), lhist=20, xlim=range(x), ylim=range(y), ...){
## set up layout and graphical parameters
layMat <- matrix(c(1,4,3,2), ncol=2)
layout(layMat, widths=c(5/7, 2/7), heights=c(2/7, 5/7))
ospc <- 0.5 # outer space
pext <- 4 # par extension down and to the left
bspc <- 1 # space between scatter plot and bar plots
par. <- par(mar=c(pext, pext, bspc, bspc), oma=rep(ospc, 4)) # plot parameters
## barplot and line for x (top)
xhist <- hist(x, breaks=seq(xlim[1], xlim[2], length.out=lhist), plot=FALSE)
par(mar=c(0, pext, 0, 0))
barplot(xhist$density, axes=FALSE, ylim=c(0, max(xhist$density)), space=0, col=histCols[1])
## barplot and line for y (right)
yhist <- hist(y, breaks=seq(ylim[1], ylim[2], length.out=lhist), plot=FALSE)
par(mar=c(pext, 0, 0, 0))
barplot(yhist$density, axes=FALSE, xlim=c(0, max(yhist$density)), space=0, col=histCols[2], horiz=TRUE)
## overlap
dx <- density(x)
dy <- density(y)
par(mar=c(0, 0, 0, 0))
plot(dx, col=histCols[1], xlim=range(c(dx$x, dy$x)), ylim=range(c(dx$y, dy$y)),
lwd=4, type="l", main="", xlab="", ylab="", yaxt="n", xaxt="n", bty="n"
)
points(dy, col=histCols[2], type="l", lwd=3)
## scatter plot
par(mar=c(pext, pext, 0, 0))
plot(x, y, xlim=xlim, ylim=ylim, ...)
}
就这样:
scatterWithHists(x,y, histCols=c("lightblue","orange"))
你得到:
如果您绝对想使用 ggMargins
,请查找 xparams
和 yparams
。它说您可以使用它们向 x-margin 和 y-margin 发送额外的参数。我只成功地发送了颜色等微不足道的东西。但也许发送类似 xlim
的内容会有所帮助。
不确定在这里复制我对问题 you mentioned 的回答是否是个好主意,但我仍然无权发表评论,否则请告诉我。
我找到了似乎能很好解决这个问题的程序包 (ggpubr
),它考虑了几种显示数据的可能性。
包的 link 是 here, and in this link 你会找到一个很好的教程来使用它。为了完整起见,我附上了我转载的示例之一。
我先安装了这个包(需要devtools
)
if(!require(devtools)) install.packages("devtools")
devtools::install_github("kassambara/ggpubr")
对于针对不同组显示不同直方图的特定示例,它提到了与 ggExtra
相关的内容:"One limitation of ggExtra
is that it can’t cope with multiple groups in the scatter plot and the marginal plots. In the R code below, we provide a solution using the cowplot
package." 在我的例子中,我必须安装后一个包:
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))
哪个对我有用:
我正在尝试创建一个带有边际直方图的散点图,如 this question 中所示。 我的数据是两个(数字)变量,它们共享七个离散(有点)对数间隔的级别。
我在 ggExtra
包中的 ggMarginal
的帮助下成功完成了这项工作,但是我对结果不满意,因为使用与散点图,事情不排队。
如下所示,直方图条偏向数据点本身的右侧或左侧。
library(ggMarginal)
library(ggplot2)
x <- rep(log10(c(1,2,3,4,5,6,7)), times=c(3,7,12,18,12,7,3))
y <- rep(log10(c(1,2,3,4,5,6,7)), times=c(3,1,13,28,13,1,3))
d <- data.frame("x" = x,"y" = y)
p1 <- ggMarginal(ggplot(d, aes(x,y)) + geom_point() + theme_bw(), type = "histogram")
一个可能的解决方案是将直方图中使用的变量更改为因子,以便它们与散点图轴很好地对齐。
这在使用 ggplot
:
p2 <- ggplot(data.frame(lapply(d, as.factor)), aes(x = x)) + geom_histogram()
然而,当我尝试使用 ggMarginal
执行此操作时,我没有得到想要的结果 - ggMarginal
直方图似乎仍在将我的变量视为数字。
p3 <- ggMarginal(ggplot(d, aes(x,y)) + geom_point() + theme_bw(),
x = as.factor(x), y = as.factor(y), type = "histogram")
如何确保直方图条形位于数据点的中心?
我绝对愿意接受不涉及使用 ggMarginal
的答案。
如果你愿意尝试 baseplotting,这里有一个函数:
plots$scatterWithHists <- function(x, y, histCols=c("lightblue","lightblue"), lhist=20, xlim=range(x), ylim=range(y), ...){
## set up layout and graphical parameters
layMat <- matrix(c(1,4,3,2), ncol=2)
layout(layMat, widths=c(5/7, 2/7), heights=c(2/7, 5/7))
ospc <- 0.5 # outer space
pext <- 4 # par extension down and to the left
bspc <- 1 # space between scatter plot and bar plots
par. <- par(mar=c(pext, pext, bspc, bspc), oma=rep(ospc, 4)) # plot parameters
## barplot and line for x (top)
xhist <- hist(x, breaks=seq(xlim[1], xlim[2], length.out=lhist), plot=FALSE)
par(mar=c(0, pext, 0, 0))
barplot(xhist$density, axes=FALSE, ylim=c(0, max(xhist$density)), space=0, col=histCols[1])
## barplot and line for y (right)
yhist <- hist(y, breaks=seq(ylim[1], ylim[2], length.out=lhist), plot=FALSE)
par(mar=c(pext, 0, 0, 0))
barplot(yhist$density, axes=FALSE, xlim=c(0, max(yhist$density)), space=0, col=histCols[2], horiz=TRUE)
## overlap
dx <- density(x)
dy <- density(y)
par(mar=c(0, 0, 0, 0))
plot(dx, col=histCols[1], xlim=range(c(dx$x, dy$x)), ylim=range(c(dx$y, dy$y)),
lwd=4, type="l", main="", xlab="", ylab="", yaxt="n", xaxt="n", bty="n"
)
points(dy, col=histCols[2], type="l", lwd=3)
## scatter plot
par(mar=c(pext, pext, 0, 0))
plot(x, y, xlim=xlim, ylim=ylim, ...)
}
就这样:
scatterWithHists(x,y, histCols=c("lightblue","orange"))
你得到:
如果您绝对想使用 ggMargins
,请查找 xparams
和 yparams
。它说您可以使用它们向 x-margin 和 y-margin 发送额外的参数。我只成功地发送了颜色等微不足道的东西。但也许发送类似 xlim
的内容会有所帮助。
不确定在这里复制我对问题 you mentioned 的回答是否是个好主意,但我仍然无权发表评论,否则请告诉我。
我找到了似乎能很好解决这个问题的程序包 (ggpubr
),它考虑了几种显示数据的可能性。
包的 link 是 here, and in this link 你会找到一个很好的教程来使用它。为了完整起见,我附上了我转载的示例之一。
我先安装了这个包(需要devtools
)
if(!require(devtools)) install.packages("devtools")
devtools::install_github("kassambara/ggpubr")
对于针对不同组显示不同直方图的特定示例,它提到了与 ggExtra
相关的内容:"One limitation of ggExtra
is that it can’t cope with multiple groups in the scatter plot and the marginal plots. In the R code below, we provide a solution using the cowplot
package." 在我的例子中,我必须安装后一个包:
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))
哪个对我有用: