1

Consider a data set like this:

x=jitter(seq(1,100,1), amount = 8)
y=2*x+rnorm(length(x),mean =20,sd=10)
df=data.frame(x,y)
lm_xy=lm(data=df,y~x)

I want to create a scatter plot with regression line and insert a histogram of residuals (with lm_xy) rotated as to match the slope of regression line.

The plot must look like this:

Regression with inset histogram of residuals

Taken from here. I know that it can be done with viewport from the grid package, but after try it I couldn't. Please, could you give me a hint to make it in ggplot2 from R?

Edit

This is the best I could do:

x=jitter(seq(1,100,1), amount = 8)
y=2*x+rnorm(length(x),mean =20,sd=10)
df=data.frame(x,y)
lm_xy=lm(data=df,y~x)
#get angle with 'deg' function from lm_xy
deg = function(rad) {
  return((180 * rad) / pi)
}


angle_sp=deg(atan(lm_xy$coefficients[2]))

res_xy=hist(lm_xy$residuals,breaks = 20)
res_xy=data.frame(breaks=res_xy$breaks[-1],counts=res_xy$counts)


resp=ggplot(h,aes(x,y))+geom_bar(stat = "identity", 
                                 color="black",fill="grey",size=1)+
  annotate(geom="segment", x = 0, xend = 0, y = -4, yend = max(h$y)+4,
           colour = "blue",size=1)+
  scale_x_continuous(breaks = seq(-10,10,20))+
  theme(
    panel.background = element_blank(),
    plot.margin = margin(0, 0, 2, 0, "cm"),
    axis.line=element_blank(),
    axis.text.y=element_blank(),
    axis.ticks = element_line(size=1,margin(0,0,0,0)),
    axis.text.x = element_text(margin = margin(-0.5,0,2,0, "cm")),
    axis.title.x=element_blank(),
    axis.title.y=element_blank(),
    panel.border = element_blank(),
    plot.background = element_rect(fill = "transparent",colour = NA)
  )

pdf("plot.pdf")
grid.newpage() 
plot(df$x,df$y)
abline(b=lm_xy$coefficients[2],a = lm_xy$coefficients[1])
pushViewport(viewport(x=.13,y=.81,width=.21,height=.24,just=c("left","top")))

grid.roundrect()
popViewport()
pushViewport(viewport(x=.3,y=0.85,angle=-63.6,width=.2,height=.35,just=c("left","top"))) 
par(plt = gridPLT(), new=TRUE)
print(resp,newpage = F)

dev.off()

This is the output:

enter image description here

jealcalat
  • 147
  • 9
  • 3
    What doesn't work with [this answer](https://stackoverflow.com/questions/5219671/it-is-possible-to-create-inset-graphs) ? – erocoar Jan 03 '18 at 23:56

1 Answers1

1

This will require some tweaking to move the f grob around, but I think it should get you closer.

From here

library(tidyverse)

f <- ggplot(diamonds, aes(carat)) +
  geom_histogram()

ggplot(mtcars, aes(wt, mpg)) + geom_point()
print(f, vp = grid::viewport(width = 0.5, height=0.5, angle = -45))
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
#> Warning in grid.Call.graphics(L_setviewport, vp, TRUE): cannot clip to
#> rotated viewport

#> Warning in grid.Call.graphics(L_setviewport, vp, TRUE): cannot clip to
#> rotated viewport

Created on 2018-01-04 by the reprex package (v0.1.1.9000).

Harrison
  • 303
  • 2
  • 9