2

I have been trying this for enough time and I just have to ask... It seems very basic and it has probably been asked before, but I cannot find any post that applies to my particular situation.

Really simple, I have 2 data frames with the same grouping variables but different data I want to plot together, one as bars, and another as points on top.

I am using mtcars for this example. I have my ID variables as the car model, then I use two grouping variables carb and cyl that are in both my data frames.

One data frame has the max disp value per carb and cyl so it's shorter (I filled in missing values as 0 for all the carb-cyl combinations); I want to plot it as bars.

The other data frame has the individual disp values per model, and I want to plot it on top as points.

This is my approach, but the resulting plot is really wrong, the colors and points positions need to be adjusted there... Ideally I would like all points to be black, but I seem to only have them separated by group if I do color. For the positioning, it goes inside a function so should work for any number of levels in the data frame grouping variables.

mtcars$model <- rownames(mtcars)
mtcars$cyl <- as.factor(as.character(mtcars$cyl))
mtcars$carb <- as.factor(as.character(mtcars$carb))

mydf1 <- as.data.frame(data.table::data.table(mtcars)[, list(max=max(disp)), by=list(cyl=cyl, carb=carb)])

mydf2 <- mtcars[,c(2,3,11,12)]
zerodf <- expand.grid(cyl=unique(mtcars$cyl), carb=unique(mtcars$carb))

mydf1 <- merge(mydf1, zerodf, all=TRUE)
mydf1$max[which(is.na(mydf1$max))] <- 0

P <- ggplot2::ggplot(data=NULL) +
  ggplot2::geom_bar(data=mydf1, ggplot2::aes(carb, max, fill=cyl), position="dodge", stat="identity") +
  ggplot2::scale_fill_manual(values=c("blue","red","grey"))

P <- P + ggplot2::geom_point(data=mydf2, ggplot2::aes(carb, disp, color=cyl), position=ggplot2::position_dodge(width=0.5), shape=3, size=5, show.legend=FALSE)

test

stefan
  • 90,330
  • 6
  • 25
  • 51
DaniCee
  • 2,397
  • 6
  • 36
  • 59

1 Answers1

4

The simple issue is the coloring of the points. To get black points simply map cyl on the group aesthetic in the geom_point layer. The tricky part is the positioning. To get the positioning of the points right you have to fill up mydf2 to include all combinations of cyl and carb as you have already done for mydf1. To this end I use tidyr::complete. Try this:

library(ggplot2)

mtcars$model <- rownames(mtcars)
#head(mtcars)

mtcars$cyl <- as.factor(as.character(mtcars$cyl))
mtcars$carb <- as.factor(as.character(mtcars$carb))
#summary(mtcars)
mydf1 <- as.data.frame(data.table::data.table(mtcars)[, list(max=max(disp)), by=list(cyl=cyl, carb=carb)])

mydf2 <- mtcars[,c(2,3,11,12)]

zerodf <- expand.grid(cyl=unique(mtcars$cyl), carb=unique(mtcars$carb))
mydf1 <- merge(mydf1, zerodf, all=TRUE)
mydf1$max[which(is.na(mydf1$max))] <- 0

mydf2 <- tidyr::complete(mydf2, carb, cyl)

ggplot(data = NULL, aes(group = cyl)) +
  geom_bar(data=mydf1, aes(carb, max, fill=cyl), position="dodge", stat="identity") +
  scale_fill_manual(values=c("blue","red","grey")) +
  geom_point(data=mydf2, aes(carb, disp, group=cyl), position = position_dodge(width = 0.9), shape=3, size=5, show.legend=FALSE)
#> Warning: Removed 9 rows containing missing values (geom_point).

stefan
  • 90,330
  • 6
  • 25
  • 51
  • just a bit bothered with the `warnings` here... any way of taking care of them? – DaniCee Aug 20 '20 at 09:17
  • and another question... in case I wanted to keep the group coloring for the points... why if I do `color=cyl` in `geom_point` I don't get the same `blue`, `red`, `grey` colors? – DaniCee Aug 20 '20 at 09:21
  • Each aesthetic has its own scale. With `scale_fill_manual` you set colors for the `fill` aes. To set the palette for the `color` aes you have to add `scale_color_manual(values=c("blue","red","grey"))` or add the additional argument `aesthetics = c("fill", "color")` to `scale_fill_manual`. – stefan Aug 20 '20 at 09:43
  • oh right! sorry that was a silly question... can we hide the warnings or avoid them? – DaniCee Aug 20 '20 at 10:06
  • (: Good question. And the answer is yes. Following https://stackoverflow.com/questions/13286531/how-to-suppress-warnings-when-plotting-with-ggplot one can add `na.rm = TRUE` to `geom_point` to suppress the warnings. – stefan Aug 20 '20 at 10:11