如何在插值数据图的边界上绘制原始数据的直方图

我想在同一个图中显示每个预测器的内插数据和原始数据的直方图。 我曾在其他线索中看到过这样的情况,人们会解释如何对散点图中显示的相同数据做边缘直方图,但在这种情况下,直方图是基于其他数据(原始数据)。

假设我们看到价格与钻石数据集中的克拉和表格有关:

library(ggplot2)
p = ggplot(diamonds, aes(x = carat, y = table, color = price)) + geom_point()

我们可以添加一个边缘频率图,例如ggMarginal

library(ggExtra)    
ggMarginal(p)

在这里输入图像描述

我们如何添加类似于预测钻石价格的瓦块图?

library(mgcv)
model = gam(price ~ s(table, carat), data = diamonds)
newdat = expand.grid(seq(55,75, 5), c(1:4))
names(newdat) = c("table", "carat")
newdat$predicted_price = predict(model, newdat)

ggplot(newdat,aes(x = carat, y = table, fill = predicted_price)) + 
    geom_tile()

在这里输入图像描述

理想情况下,直方图甚至超出瓦片图的边界,因为这些数据点也会影响预测。 但是,我会很高兴知道如何绘制瓦片图中显示的范围的直方图。 (也许超出范围的值可能会以不同的颜色添加到极值中。)

PS。 我设法使用链接线程中接受的答案的方法或多或少地将直方图对齐到一个拼贴图边的边缘,但前提是我移除了所有类型的标签。 如果可能的话,保留颜色图例会特别好。

编辑: eipi10提供了一个很好的解决方案。 我试图稍微修改它以添加样本大小的数字,并以图形方式显示绘图范围之外的值,因为它们也会影响插值。 我打算在侧面的直方图中以不同的颜色包含它们。 我在此试图将它们计算在绘图范围的上限和下限。 我也试图在样地的某个地方绘制样本数量。 但是,我两人都失败了。

这是我试图以图形方式说明绘图区域之外的样本大小:

plot_data = diamonds
plot_data <- transform(plot_data, carat_range = ifelse(carat < 1 | carat > 4, "outside", "within"))
plot_data <- within(plot_data, carat[carat < 1] <- 1)
plot_data <- within(plot_data, carat[carat > 4] <- 4)
plot_data$carat_range = as.factor(plot_data$carat_range)

p2 = ggplot(plot_data, aes(carat, fill = carat_range)) +
    geom_histogram() +
    thm +
    coord_cartesian(xlim=xrng)

我尝试用geom_text将样本大小添加到数字中。 我尝试将它安装在最右侧的面板中,但很难(不适合我)进行调整。 我试图把它放在主图上(反正这可能不是最好的解决方案),但它也不起作用(它删除了直方图和图例,在右边,它没有绘制所有的geom_texts)。 我也尝试添加第三行的情节,并写在那里。 我的尝试:

n_table_above = nrow(subset(diamonds, table > 75))
n_table_below = nrow(subset(diamonds, table < 55))
n_table_within = nrow(subset(diamonds, table >= 55 & table <= 75))

text_p = ggplot()+ 
    geom_text(aes(x = 0.9, y = 2, label = paste0("N(>75) = ", n_table_above)))+
    geom_text(aes(x = 1, y = 2, label = paste0("N = ", n_table_within)))+
    geom_text(aes(x = 1.1, y = 2, label = paste0("N(<55) = ", n_table_below)))+ 
    thm

library(egg) 
pobj = ggarrange(p2, ggplot(), p1, p3,
                 ncol=2, widths=c(4,1), heights=c(1,4))

grid.arrange(pobj, leg, text_p, ggplot(), widths=c(6,1), heights =c(6,1))

我会非常乐意接受任何一项或两项任务的帮助(将样本大小添加为文本并在绘制范围之外添加不同颜色的值)。


根据你的评论,也许最好的方法是滚动你自己的布局。 下面是一个例子。 我们创建边缘图作为单独的ggplot对象,并将它们与主图相关联。 我们也提取了这个传说,并把它放在边缘地块之外。

建立

library(ggplot2)
library(cowplot)

# Function to extract legend
#https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs
g_legend<-function(a.gplot){
  tmp <- ggplot_gtable(ggplot_build(a.gplot))
  leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
  legend <- tmp$grobs[[leg]]
  return(legend) }

thm = list(theme_void(),
           guides(fill=FALSE),
           theme(plot.margin=unit(rep(0,4), "lines")))

xrng = c(0.6,4.4)
yrng = c(53,77)

地块

p1 = ggplot(newdat, aes(x = carat, y = table, fill = predicted_price)) + 
  geom_tile() +
  theme_classic() +
  coord_cartesian(xlim=xrng, ylim=yrng)

leg = g_legend(p1)

p1 = p1 + thm[-1]

p2 = ggplot(diamonds, aes(carat)) +
  geom_line(stat="density") +
  thm +
  coord_cartesian(xlim=xrng)

p3 = ggplot(diamonds, aes(table)) +
  geom_line(stat="density") +
  thm + 
  coord_flip(xlim=yrng)

plot_grid(
  plot_grid(plotlist=list(p2, ggplot(), p1, p3), ncol=2, 
            rel_widths=c(4,1), rel_heights=c(1,4), align="hv", scale=1.1),
  leg, rel_widths=c(5,1))

在这里输入图像描述

更新:关于你对地块之间空间的评论:这是一个plot_grid的致命弱点,我不知道是否有办法解决这个问题。 另一种选择是实验性egg包装中的ggarrange ,它不会在ggarrange地块之间增加太多空间。 此外,您需要先保存ggarrange的输出,然后用图例布局保存的对象。 如果在grid.arrange运行ggarrangegrid.arrange得到两个重叠的图形副本:

# devtools::install_github('baptiste/egg')
library(egg) 

pobj = ggarrange(p2, ggplot(), p1, p3, 
                 ncol=2, widths=c(4,1), heights=c(1,4))

grid.arrange(pobj, leg, widths=c(6,1))

在这里输入图像描述

链接地址: http://www.djcxy.com/p/68929.html

上一篇: How to plot histograms of raw data on the margins of a plot of interpolated data

下一篇: Subscript a title in a Graph (ggplot2) with label of another file