I'd like to add histograms in base R to the margins of a plot, I've tried many ways, and used points and segments to plot the values calculated from a histogram. The challenge is that after plotting the data, the width of the bars have to be set manually in order to show a histogram like margin plot.
# Inspired from
# https://github.com/ChrKoenig/R_marginal_plot/blob/master/marginal_plot.R
par(mfrow = c(1,2), mar =c(4,4,3,3), cex = 1.4)
set.seed(1234)
n = 250
x.1 = rnorm(n, mean = 15, sd = 5)
y.1 = rnorm(n, mean = 5, sd = 2)
x.2 = rnorm(n, mean = 15, sd = 1)
y.2 = rnorm(n, mean = 5, sd = .5)
x = x.1
y = y.1
moreargs$xlim[1] <- range(c(-3,x.1,x.2, max(x.1,x.2) 5))[1]
moreargs$xlim[2] <- range(c(-3,x.1,x.2, max(x.1,x.2) 5))[2]
moreargs$ylim[1] <- range(c(y.1,y.2,max(y.1,y.2) 5))[1]
moreargs$ylim[2] <- range(c(y.1,y.2,max(y.1,y.2) 5))[2]
require(scales)
# plotting
data = data.frame(x = as.numeric(x), y = as.numeric(y))
group_colors = "black"
ifelse(test = !is.null(data$group),
yes = data_split <- split(data, data$group),
no = data_split <- list(data))
orig_par = par(no.readonly = T)
par(mar = c(0.25,5,1,0))
layout(matrix(1:4, nrow = 2, byrow = T), widths = c(10,3), heights = c(3,10))
histval = hist(x = data_split[[1]]$x, plot = FALSE)
# upper density plot
plot(NULL, type = "n",
ylab = "Counts",
xlim = moreargs$xlim,
ylim = c(0, max(histval$counts)),
main = NA, axes = F)
points(histval$mids,histval$counts, type= "h", lwd = 33, lend="butt", col = 'gray60')
# points(histval$mids,histval$counts-1, type= "h", lwd = 30, lend="butt", col = 'gray80')
axis(2, tck = 0.04)
# (add an empty plot in the corner)
par(mar = c(0.25,0.25,0,0))
plot.new()
# main plot
par(mar = c(4,5,0,0))
plot(y.1~x.1,
ylim = moreargs$ylim,
xlim = moreargs$xlim,
pch = 19, col = scales::alpha("black",.8), ylab = "Y",xlab = "X")
axis(3, labels = F, tck = 0.01)
axis(4, labels = F, tck = 0.01)
box()
# right density plot
par(mar = c(4,0.25,0,1))
histval.y = hist(x = data_split[[1]]$y, plot = FALSE)
plot(NULL, type = "n",
xlab = "Counts",
xlim = c(0, max(histval$counts)),
ylim = moreargs$ylim,
main = NA, axes = F)
segments(x0 = 0,x1 = histval.y$counts,
y0 = histval.y$mids,y1 = histval.y$mids,
lwd = rep(c(46,2), each = length(histval.y$counts)), col = "gray60", lend="butt")
axis(1,tck=0.04)
par(orig_par)
Is there a way to make histograms in base R in the margin of plots?
CodePudding user response: