Home > Back-end >  How to plot histograms in base R in the margin of a plot
How to plot histograms in base R in the margin of a plot

Time:02-10

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)

enter image description here

Is there a way to make histograms in base R in the margin of plots?

CodePudding user response:

  1. Using layout, you can set a space to 0 so that it does not require a plot, it is empty space.

  2. hist does not support horizontal mode, and recommendations (enter image description here

  • Related