I have a question that seems simple to achieve but I'm not sure how to do it. I'm plotting a data frame and I'm layering different variables on to one plot, but I was wondering if there was a way to facet my plot. I want the top 2 trend lines on one plot and to have the bar graph underneath. Usually you can do this with facet_grid or facet_wrap but I'm not sure how to since they all belong in the same group.
sample_df <- data.frame(x = c(1,2,3,4,5,6,7,8), y = c(rnorm(8, mean = 200, sd = 28)), y1 = c(rnorm(8, mean = 240, sd = 57)),y2 = c(rnorm(8, mean = 0, sd = 27)))
sample_df$group <- "rand_nums"
sample_df$type <- ifelse(sample_df$y2 < 0, "neg", "pos")
sample_df %>% ggplot()+
geom_line(aes(x = x, y = y, group = group), color = "forestgreen", size = 2)+
geom_line(aes(x = x, y = y1, group = group),color = "violet",size = 2)+
geom_bar(stat = "identity", aes(x = x, y = y2, group = group, fill = type))+
scale_fill_manual(name = "Pos or Neg",
values = c("pos" = "yellow", "neg" = "red"))
You did not notice, but in the process of copying and pasting your code, you added some stuff that you don't want in there (probably the script to upload your picture). I am referring to the first line of ggplot().
This looks like a great use case for the patchwork package. Unfortunately, it's not yet on CRAN, but you can download it from Github in the following way:
# Install the remotes package if you haven't done so yet
install.packages("remotes")
install_github("thomasp85/patchwork")
# Code for creating the sample_df dataset
# ...
#....
p <- ggplot(data = sample_df)
p1 <- p +
geom_line(aes(x = x, y = y, group = group), color = "forestgreen", size = 2)+
geom_line(aes(x = x, y = y1, group = group),color = "violet",size = 2)
p2 <- p +
geom_bar(stat = "identity", aes(x = x, y = y2, group = group, fill = type))+
scale_fill_manual(name = "Pos or Neg",
values = c("pos" = "yellow", "neg" = "red"))
p1 + p2 + plot_layout(ncol = 1)
I am not sure, but it's always a good idea to update your packages whenever you think about it. If you use RStudio, there is a very convenient way to do it by clicking on the "Packages" tab (usually on the bottom-right corner of the layout) and then click on "Update". RStudio will automatically let you know the packages which need updates. Click on "Select All" and finally on "Install Updates". Be aware that it COULD take a bit of time.
With some data reshaping, you can actually create a single facetted plot, as shown in the code below, although you may ultimately decide that you need the greater flexibility that comes with generating separate plots.
# Setup
library(tidyverse)
# Sample data
set.seed(2)
sample_df <- data.frame(x = 1:8,
y = rnorm(8, mean = 200, sd = 28),
y1 = rnorm(8, mean = 240, sd = 57),
y2 = rnorm(8, mean = 0, sd = 27))
sample_df$group <- "rand_nums"
sample_df$type <- ifelse(sample_df$y2 < 0, "neg", "pos")
# Reshape and plot
# Reshape data to long format and add grouping column to mark the
# facet each data series belongs to
sample_df_long = sample_df %>%
gather(key, value, y, y1, y2) %>%
mutate(facet.group = case_when(key %in% c("y", "y1") ~ "line",
TRUE ~ "bar") %>% fct_rev())
ggplot(data=sample_df_long, aes(x, value)) +
geom_line(data=. %>% filter(facet.group=="line"), aes(colour=key),
size=2) +
geom_col(data=. %>% filter(facet.group=="bar"), aes(fill=type)) +
facet_grid(facet.group ~ ., scales="free_y") +
theme_bw() +
theme(strip.text=element_blank()) +
guides(color = guide_legend(order = 1),
fill = guide_legend(order = 2, reverse=TRUE)) +
scale_fill_manual(values=c("red","blue")) +
scale_colour_manual(values=c("violet", "forestgreen")) +
labs(x="", y="", colour="Line Title", fill="Pos or Neg") +
expand_limits(y=0)
I think these are all great solutions to my problem. Unfortunately I cannot update my packages frequently due to IT security, so I do not have ggplot2 (>= 3.00) yet.
If you have issues with using these packages, and in general have issues with IT and package updates, you can fairly easily do this in base R as well?
sample_df = sample_df %>%
mutate(bar_color = ifelse(y2>0, 'yellow', 'red'))
par(mfrow = c(2,1))
plot(y~x, data = sample_df, col = 'forestgreen', type = 'l', ylim = range(c(sample_df$y, sample_df$y1)))
lines(y1~x, data = sample_df, col = 'violet', type = 'l')
barplot(height = sample_df$y2, data = sample_df, col = sample_df$bar_color)
That being said I really like @joels solution of making a dummy column to facet over. That may be the only ggplot solution here that doesn't have additional dependencies.
... and then of course there's always photoshop/illustrator/powerpoint. This is of course not the optimal way to do this, but if you are having issues with IT and need graphs for your research then we'll lower our pitchforks and look the other way