2

Suppose data

set.seed(42)
a <- rnorm(100)
b <- rnorm(100)+1

which I would like to plot side-by-side using multhist().

multhist(list(a,b), yaxs="i")

Now I would like to draw a box around them

box(which = "plot", lty = "solid")

which gives me

using multhist

with some space between the bottom line of the box and the bars.

Had I used hist() to plot only one graph, the ouput would have been without gap between box and bars:

using hist

Is there a different trick to get such an output in multhist()?

bumblebee
  • 1,116
  • 8
  • 20

2 Answers2

1

Just add "space=c(0,0)" and "ylim" and you good to go:

multhist(list(a,b), yaxs="i", space=c(0,0), ylim=c(0,40))

enter image description here

  • Ah, you're talking about the space between bars. I meant the space between bars and the bottom line of the box. I have made this more explicit in the OP. – bumblebee Apr 10 '20 at 13:53
  • There is a gap at -2.5 and 3.5 because those values in your distribution of list(a, b) are missing. In your hist() example, you are only plotting a, which you can see that it is limited 2.5. – Kamran Esmaeili Apr 10 '20 at 14:00
  • Thanks for clarifying. However, I am not worrying about the space between bars. I am referring to the space between all bars and the box around the figure. I have now highlighted this in the first screenshot. – bumblebee Apr 10 '20 at 14:02
  • Think I misunderstood your question initially, apologies. Is that what you had in mind? If you would like to also limit the side-gaps you can use xlim=c(0.5, 13.5). Not sure about the values, but these seem to work. – Kamran Esmaeili Apr 10 '20 at 14:20
  • No worries! Thanks for finding the `ylim=c(0,40)` solution. Do you think there is also a way that does not require manually setting the 40? – bumblebee Apr 10 '20 at 14:43
  • Maybe you can estimate the count by first using the multhist function and find the maximum counts (in the list) and then reuse the multhist function to plot with the correct ylim. Other option was suggested by someone else which is using: multhist(list(a,b), yaxs = "i", space=c(0,0)) box(bty = "7") abline(h = 0) abline(v=-0.99) – Kamran Esmaeili Apr 10 '20 at 15:03
1

I think setting ylim mentioned by @KamranEsmaeili is a standard solution. Here I provided a tricky way that doesn't require manually setting the upper limit 40.


multhist() is based on the built-in barplot() and it always sets the lower limit of y-coordinate of the plotting region less than 0. You can use par("usr")[3] to check this fact. I just came up with a tricky method that adjusts the box type to "7" to suppress the bottom line and add a new bottom line at 0 by abline(h = 0).

library(plotrix)
set.seed(42)
a <- rnorm(100)
b <- rnorm(100) + 1
multhist(list(a,b))
#---------------------------------
box(bty = "7") # bty is one of "o"(default), "l", "7", "c", "u", and "]".
abline(h = 0)


Edit

If you don't like the right line extending beyond the x axis, then you can replace box() with rect() so that you can specify positions of four sides by yourself. Remember to add xpd = TRUE, or the line width will look thinner than y-axis.

multhist(list(a,b))
x <- par("usr")
rect(x[1], 0, x[2], x[4], xpd = TRUE)
Darren Tsai
  • 32,117
  • 5
  • 21
  • 51
  • Thanks! Very elegant but unfortunately the right line extends beyond the abline. Do you think this can fixed? – bumblebee Apr 10 '20 at 18:17
  • @bumblebee I cannot deal with that...I figure out another method. See the edit. – Darren Tsai Apr 10 '20 at 19:31
  • @bumblebee if you prefer the second method, remember to add `xpd = TRUE`, or the line width of the rectangle will look thinner than y-axis. – Darren Tsai Apr 11 '20 at 16:15