How to add a vertical blank space between straight and inverted geom_density() with ggplot2 - r

I am trying to reproduce this kind of Figure, with two densities, a first one pointing upwards and a second one pointing downwards. I would also like to have some blank space between the two densities.
Here is the code I am currently using.
library(hrbrthemes)
library(tidyverse)
library(RWiener)
# generating data
df <- rwiener(n = 1e2, alpha = 2, tau = 0.3, beta = 0.5, delta = 0.5)
df %>%
ggplot(aes(x = q) ) +
geom_density(
data = . %>% filter(resp == "upper"),
aes(y = ..density..),
colour = "steelblue", fill = "steelblue",
outline.type = "upper", alpha = 0.8, adjust = 1, trim = TRUE
) +
geom_density(
data = . %>% filter(resp == "lower"),
aes(y = -..density..), colour = "orangered", fill = "orangered",
outline.type = "upper", alpha = 0.8, adjust = 1, trim = TRUE
) +
# stimulus onset
geom_vline(xintercept = 0, lty = 1, col = "grey") +
annotate(
geom = "text",
x = 0, y = 0,
# hjust = 0,
vjust = -1,
size = 3, angle = 90,
label = "stimulus onset"
) +
# aesthetics
theme_ipsum_rc(base_size = 12) +
theme(axis.text.y = element_blank() ) +
labs(x = "Reaction time (in seconds)", y = "") +
xlim(0, NA)
Which results in something like...
How could I add some vertical space between the two densities to reproduce the above Figure?

If you want to try without faceting, you're probably best to just plot the densities as polygons with adjusted y values according to your desired spacing:
s <- 0.25 # set to change size of the space
ud <- density(df$q[df$resp == "upper"])
ld <- density(df$q[df$resp == "lower"])
x <- c(ud$x[1], ud$x, ud$x[length(ud$x)],
ld$x[1], ld$x, ld$x[length(ld$x)])
y <- c(s, ud$y + s, s, -s, -ld$y - s, -s)
df2 <- data.frame(x = x, y = y,
resp = rep(c("upper", "lower"), each = length(ud$x) + 2))
df2 %>%
ggplot(aes(x = x, y = y, fill = resp, color = resp) ) +
geom_polygon(alpha = 0.8) +
scale_fill_manual(values = c("steelblue", "orangered")) +
scale_color_manual(values = c("steelblue", "orangered"), guide = guide_none()) +
geom_vline(xintercept = 0, lty = 1, col = "grey") +
annotate(
geom = "text",
x = 0, y = 0,
# hjust = 0,
vjust = -1,
size = 3, angle = 90,
label = "stimulus onset"
) +
# aesthetics
theme_ipsum_rc(base_size = 12) +
theme(axis.text.y = element_blank() ) +
labs(x = "Reaction time (in seconds)", y = "")

you can try facetting
set.seed(123)
q=rbeta(100, 0.25, 1)
df_dens =data.frame(gr=1,
x=density(df$q)$x,
y=density(df$q)$y)
df_dens <- rbind(df_dens,
data.frame(gr=2,
x=density(df$q)$x,
y=-density(df$q)$y))
ggplot(df_dens, aes(x, y, fill = factor(gr))) +
scale_x_continuous(limits = c(0,1)) +
geom_area(show.legend = F) +
facet_wrap(~gr, nrow = 2, scales = "free_y") +
theme_minimal() +
theme(strip.background = element_blank(),
strip.text.x = element_blank(),
axis.text.y = element_blank(),
axis.title.y = element_blank())
The space between both plots can be increased using panel.spacing = unit(20, "mm"). Instead of facet_grid you can also try facet_grid(gr~., scales = "free_y")

Related

facet_wrap not showing the second facet with geom_density_ridges

I am trying to subset parts of a data you can download the csv from here and read it as datplot. This is what its head looks like:
> head(datplot)
# A tibble: 6 × 3
bta electrode value
<chr> <chr> <dbl>
1 b0 Fz 3.03
2 b0 Cz 1.78
3 b0 Pz -1.05
4 b0 Fz 3.78
5 b0 Cz 2.82
6 b0 Pz -0.242
As you can see, the data has a variable named bta with levels "b0" and "b1" and values from a particular distribution. What I am trying to do, is wrap the two facets but I can't manage to do it.
This is the ggplot code I am using at the moment:
time <- "225"
col <- c("#004d8d", "#cc2701", "#e5b400")
p1 <- datplot %>% ggplot(mapping = aes(x=value, y=factor(electrode, level = c('Fz','Cz','Pz')), group = electrode, color = electrode)) +
scale_y_discrete() +
geom_rect(data=data.frame(), inherit.aes = FALSE, mapping = aes(
ymin = 0, ymax = Inf, xmin = -0.1 * min(stdev), xmax = 0.1 * max(stdev)), fill = "black", alpha = 0.1) +
geom_density_ridges(data= subset(datplot, bta='b0'), scale = -0.5, alpha=0.2, show.legend = FALSE,
quantile_lines = TRUE, quantiles = c(0.025, 0.5, 0.975),
vline_color = alpha("white", 0.3), aes(fill = electrode)) +
#plotb1
geom_density_ridges(data= subset(datplot, bta='b1'),scale = -0.5, alpha=0.5, show.legend = FALSE,
quantile_lines = TRUE, quantiles = c(0.025, 0.5, 0.975),
vline_color = alpha("white", 0.6), aes(fill = electrode)) +
facet_wrap(~bta) +
scale_color_manual(values = col, breaks = c("Fz", "Cz", "Pz")) +
scale_fill_manual(values = col, breaks = c("Fz", "Cz", "Pz")) +
labs(title=sprintf('%s ms.',time)) +
ylab("Electrode") +
xlab(TeX(r'(Signal (µV) Posteriors $\beta_1\cdot x\; (x=1)$)')) +
theme_light() +
theme(axis.text = element_text(size = 14)) +
theme(axis.title = element_text(size = 16)) +
theme(plot.title = element_text(size = 20)) +
coord_flip(xlim = c(-8, 8), ylim = c(0.4,3.05), expand = FALSE, clip = "on")
p1
This code results only with the plot corresponding to "b0" but the other facet seems to be missing, as you can see in the following image:
And for some reason, the data that corresponds to "b1" does not appear. I am probably failing in something with the code that I am unsuccesful identifying. In case it helps, the missing plot, which I plotted alone, would look something like this:
So clearly something is failing when using both geom_density_ridges together in the previous code.
[UPDATE]
Following a comment by #Paul, I tried to not subset the data with the following code:
p1 <- datplot %>% ggplot(mapping = aes(x=value, y=factor(electrode, level = c('Fz','Cz','Pz')), group = electrode, color = electrode)) +
scale_y_discrete() +
geom_rect(data=data.frame(), inherit.aes = FALSE, mapping = aes(
ymin = 0, ymax = Inf, xmin = -0.1 * min(stdev), xmax = 0.1 * max(stdev)), fill = "black", alpha = 0.1) +
geom_density_ridges(data= datplot, scale = -0.5, alpha=0.5, show.legend = FALSE,
quantile_lines = TRUE, quantiles = c(0.025, 0.5, 0.975),
vline_color = alpha("white", 0.3), aes(fill = electrode)) +
facet_wrap(~bta) +
scale_color_manual(values = col, breaks = c("Fz", "Cz", "Pz")) +
scale_fill_manual(values = col, breaks = c("Fz", "Cz", "Pz")) +
labs(title=sprintf('%s ms.',time)) +
ylab("Electrode") +
xlab(TeX(r'(Signal (µV) Posteriors $\beta_1\cdot x\; (x=1)$)')) +
theme_light() +
theme(axis.text = element_text(size = 14)) +
theme(axis.title = element_text(size = 16)) +
theme(plot.title = element_text(size = 20)) +
coord_flip(xlim = c(-8, 8), ylim = c(0.4,3.05), expand = FALSE, clip = "on")
p1
With the same output:
Thanks for the help!
Attempted a minimal reproducible example:
library(ggplot2)
library(ggridges)
library(magrittr)
# data for testing
datplot <- data.frame(
bta = rep(c("b0", "b1"), each = 75),
electrode = rep(c("Fz","Cz","Pz"), times = 50),
value = runif(150,-2,5)
)
time <- "225"
col <- c("#004d8d", "#cc2701", "#e5b400")
p1 <- datplot %>%
ggplot(mapping = aes(x=value, y=factor(electrode, levels = c('Fz','Cz','Pz')), group = electrode, color = electrode)) +
scale_y_discrete() +
geom_density_ridges(scale = -0.5, alpha=0.2,
quantile_lines = TRUE,
quantiles = c(0.025, 0.5, 0.975),
vline_color = alpha("white", 0.3),
aes(fill = electrode)) +
facet_wrap(~bta) +
coord_flip(xlim = c(-8, 8), ylim = c(0.4,3.05), expand = FALSE, clip = "on")
p1
This produces a faceted plot which I think meets the meat of the request - there is much to be done to match desired aesthetics but this should provide a start point from which you can tweak the appearance.

How to present the results of a dataframe in a serial scale using ggplot as in the example attached?

I have this data frame :
Raw.Score = c(0,1,2,3,4,5,6,7,8)
Severity = c(-3.56553994,-2.70296933,-1.63969850,-0.81321707,-0.04629182,
0.73721320,1.61278518,2.76647043,3.94804472)
x = data.frame(Raw.Score = Raw.Score, Severity = Severity)
Raw.score are raw numbers from 0 to 8 (let's consider them as the labels of the severity numbers)
Severity are relative numbres that represent the locations of the scores in the diagram
I want to graphically present the results as in the following example using ggplot (the example includes different numbers but I want something similar)
As a fun exercise in ggplot-ing here is one approach to achieve or come close to your desired result.
Raw.Score = c(0,1,2,3,4,5,6,7,8)
Severity = c(-3.56553994,-2.70296933,-1.63969850,-0.81321707,-0.04629182,
0.73721320,1.61278518,2.76647043,3.94804472)
dat <- data.frame(Raw.Score, Severity)
library(ggplot2)
dat_tile <- data.frame(
Severity = seq(-4.1, 4.1, .05)
)
dat_axis <- data.frame(
Severity = seq(-4, 4, 2)
)
tile_height = .15
ymax <- .5
ggplot(dat, aes(y = 0, x = Severity, fill = Severity)) +
# Axis line
geom_hline(yintercept = -tile_height / 2) +
# Colorbar
geom_tile(data = dat_tile, aes(color = Severity), height = tile_height) +
# Sgements connecting top and bottom labels
geom_segment(aes(xend = Severity, yend = -ymax, y = ymax), color = "orange") +
# Axis ticks aka dots
geom_point(data = dat_axis,
y = -tile_height / 2, shape = 21, stroke = 1, fill = "white") +
# ... and labels
geom_text(data = dat_axis, aes(label = Severity),
y = -tile_height / 2 - .1, vjust = 1, fontface = "bold") +
# Bottom labels
geom_label(aes(y = -ymax, label = scales::number(Severity, accuracy = .01))) +
# Top labels
geom_point(aes(y = ymax, color = Severity), size = 8) +
geom_text(aes(y = ymax, label = Raw.Score), fontface = "bold") +
# Colorbar annotations
annotate(geom = "text", fontface = "bold", label = "MILD", color = "black", x = -3.75, y = 0) +
annotate(geom = "text", fontface = "bold", label = "SEVERE", color = "white", x = 3.75, y = 0) +
# Fixing the scales
scale_x_continuous(expand = c(0, 0)) +
scale_y_continuous(limits = c(-ymax, ymax)) +
# Color gradient
scale_fill_gradient(low = "orange", high = "red", guide = "none") +
scale_color_gradient(low = "orange", high = "red", guide = "none") +
# Get rid of all non-data ink
theme_void() +
# Add some plot margin
theme(plot.margin = rep(unit(10, "pt"), 4)) +
coord_cartesian(clip = "off")

How to apply slope plot R code to another data

I have dataframe which represents sales by model within 2 different years. 'change' column stands for absolute change by models from 2020 to 2021 while 'chng.percent' measures this change in percentages.
However, I am struggling to apply the given Code of slope plot to my data.
df <- data.frame (model = c("A", "A", "B","B"),
year = c(2020,2021,2020,2021),
sale =c(105,190,110,180),
chang = c(85,NA,70,NA),
chng.percent = c(80.9,NA, 63.6,NA))
Expected outcome (Like this)
Here's a way to do it all within ggplot using your existing data:
ggplot(df, aes(year, sale, color = model)) +
geom_line(arrow = arrow(type = "closed", angle = 20),
key_glyph = draw_key_point) +
geom_vline(aes(xintercept = year)) +
geom_text(aes(label = sale, hjust = ifelse(year == 2020, 1.3, -0.3)),
color = "black",
size = 6) +
geom_text(aes(x = min(df$year) + 0.25, y = 105,
label = paste0("+", chang[1], "; ", chng.percent[1], "%"),
color = "A"), size = 5) +
geom_text(aes(x = max(df$year) - 0.25, y = 150,
label = paste0("+", chang[3], "; ", chng.percent[3], "%"),
color = "B"), size = 5) +
theme_void(base_size = 16) +
coord_cartesian(clip = "off") +
scale_x_continuous(breaks = c(2020, 2021)) +
guides(color = guide_legend(override.aes = list(size = 5))) +
scale_color_brewer(palette = "Set1") +
theme(plot.margin = margin(30, 30, 30, 30),
aspect.ratio = 1.5,
axis.text.x = element_text(size = 20))
you can try something like this :
df <- data.frame(model = c("A", "B"),
sale_2020 =c(105,110),
sale_2021 =c(190,180),
chang = c(85,70),
chng.percent = c(80.9, 63.6))
df %>%
ggplot() +
geom_segment(aes(x = 1, xend = 2,
y = sale_2020,
yend = sale_2021,
group = model,
col = model),
size = 1.2) +
# set the colors
scale_color_manual(values = c("#468189", "#9DBEBB"), guide = "none") +
# remove all axis stuff
theme_classic() +
theme(axis.line = element_blank(),
axis.text = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank()) +
geom_text(aes(x = x, y = y, label = label),
data = data.frame(x = 1:2,
y = 10 + max(df$sale_2021),
label = c("2020", "2021")),
col = "grey30",
size = 6) +
# add vertical lines that act as axis for 2020
geom_segment(x = 1, xend = 1,
y = min(df$sale_2020) -10,
yend = max(df$sale_2020) + 81,
col = "grey70", size = 1.5) +
# add vertical lines that act as axis for 2021
geom_segment(x = 2, xend = 2,
y = min(df$sale_2021) - 80,
yend = max(df$sale_2021) + 1,
col = "grey70", size = 1.5) +
# add the success rate next to each point on 2021 axis
geom_text(aes(x = 2 + 0.08,
y = sale_2021,
label = paste0(round(sale_2021, 1))),
col = "grey30") +
# add the success rate next to each point on 2021 axis
geom_text(aes(x = 1 - 0.08,
y = sale_2020,
label = paste0(round(sale_2020, 1))),
col = "grey30") +
# add the success rate next to each point on 2020 axis
geom_text(aes(x = 2 - 0.5,
y = c(156, 135),
label = paste0(round(chng.percent, 1), "%")),
col = "grey30")

How to add common line and text as second x-axis label

I want to plot a graph. Several of my x-axis labels have a common label. So I want to add common text as label instead of several separate labels on x-axis as shown in the attached images. How can this be done?
library(dplyr)
library(forcats)
library(ggplot2)
df <- data.frame(conc = c(0, 10, 50, 100, "Positive Control"),
values = c(3, 3, 4, 5, 10),
name = c("TiO2 NP", "TiO2 NP", "TiO2 NP", "TiO2 NP", "Cyclophosamide"))
df$conc <- as.factor(df$conc)
labels2 <- paste0(df$conc, "\n", df$name)
df %>%
mutate(conc = fct_reorder(conc, values)) %>%
ggplot(aes(x = conc, y=values, fill = conc))+
geom_bar(stat = "identity",show.legend = FALSE, width = 0.6)+
scale_x_discrete(labels = labels2)+
labs(x = "\n Dose (mg/kg BW)")
I don't think there's a simple way. You have to play with ggplot2 for some time to make something really custom. Here's my example:
df %>%
mutate(
conc = fct_reorder(conc, values),
labels2 = if_else(
name == 'TiO2 NP',
as.character(conc),
paste0(conc, '\n', name)
)
) %>%
ggplot(aes(x=conc, y=values, fill = conc)) +
geom_bar(
stat = "identity",
show.legend = FALSE,
width = 0.6
) +
geom_rect(aes(
xmin = .4,
xmax = 5.6,
ymin = -Inf,
ymax = 0
),
fill = 'white'
) +
geom_text(aes(
y = -.4,
label = labels2
),
vjust = 1,
size = 3.4,
color = rgb(.3, .3, .3)
) +
geom_line(data = tibble(
x = c(.9, 4.1),
y = c(-1.2, -1.2)
),
aes(
x = x,
y = y
),
color = rgb(.3, .3, .3),
inherit.aes = FALSE
) +
geom_curve(data = tibble(
x1 = c(.8, 4.1),
x2 = c(.9, 4.2),
y1 = c(-.8, -1.2),
y2 = c(-1.2, -.8)
),
aes(
x = x1,
y = y1,
xend = x2,
yend = y2
),
color = rgb(.3, .3, .3),
inherit.aes = FALSE
) +
geom_text(aes(
x = 2.5,
y = -1.7,
label = 'TiO2 NP'
),
size = 3.4,
color = rgb(.3, .3, .3),
check_overlap = TRUE
) +
geom_text(aes(
x = 3,
y = -2.4,
label = '\n Dose (mg/kg BW)'
),
show.legend = FALSE,
check_overlap = TRUE
) +
theme_minimal() +
theme(
axis.text.x = element_blank(),
axis.title.x = element_blank()
) +
scale_y_continuous(
breaks = seq(0, 10, 2.5),
limits = c(-2.5, 10)
)
For a more automated approach, you can try placing the common variable in facet_grid with scales = "free", space = "free", to simulate a 2nd x-axis line. The rest of the code below are for aesthetic tweaks:
df %>%
mutate(conc = fct_reorder(conc, values)) %>%
ggplot(aes(x = conc, y = values, fill = conc)) +
geom_col(show.legend = F, width = 0.6) + #geom_col() is equivalent to geom_bar(stat = "identity")
facet_grid(~ fct_rev(name),
scales = "free", space = "free",
switch = "x") + #brings the facet label positions from top (default) to bottom
scale_x_discrete(expand = c(0, 0.5)) + #adjusts the horizontal space at the ends of each facet
labs(x = "\n Dose (mg/kg BW)") +
theme(axis.line.x = element_line(arrow = arrow(ends = "both")), #show line (with arrow ends) to
#indicate facet label's extent
panel.spacing = unit(0, "cm"), #adjusts space between the facets
strip.placement = "outside", #positions facet labels below x-axis labels
strip.background = element_blank()) #transparent background for facet labels

Complex Chart in R/ggplot with Proper Legend Display

This is my first question to StackExchange, and I've searched for answers that have been helpful, but haven't really gotten me to where I'd like to be.
This is a stacked bar chart, combined with a point chart, combined with a line.
Here's my code:
theme_set(theme_light())
library(lubridate)
FM <- as.Date('2018-02-01')
x.range <- c(FM - months(1) - days(1) - days(day(FM) - 1), FM - days(day(FM) - 1) + months(1))
x.ticks <- seq(x.range[1] + days(1), x.range[2], by = 2)
#populate example data
preds <- data.frame(FM = FM, DATE = seq(x.range[1] + days(1), x.range[2] - days(1), by = 1))
preds <- data.frame(preds, S_O = round(seq(1, 1000000, by = 1000000/nrow(preds))))
preds <- data.frame(preds, S = round(ifelse(month(preds$FM) == month(preds$DATE), day(preds$DATE) / 30.4, 0) * preds$S_O))
preds <- data.frame(preds, O = preds$S_O - preds$S)
preds <- data.frame(preds, pred_sales = round(1000000 + rnorm(nrow(preds), 0, 10000)))
preds$ma <- with(preds, stats::filter(pred_sales, rep(1/5, 5), sides = 1))
y.max <- ceiling(max(preds$pred_sales) / 5000) * 5000 + 15000
line.cols <- c(O = 'palegreen4', S = 'steelblue4',
P = 'maroon', MA = 'blue')
fill.cols <- c(O = 'palegreen3', S = 'steelblue3',
P = 'red')
p <- ggplot(data = preds,
mapping = aes(DATE, pred_sales))
p <- p +
geom_bar(data = reshape2::melt(preds[,c('DATE', 'S', 'O')], id.var = 'DATE'),
mapping = aes(DATE, value, group = 1, fill = variable, color = variable),
width = 1,
stat = 'identity',
alpha = 0.5) +
geom_point(mapping = aes(DATE, pred_sales, group = 2, fill = 'P', color = 'P'),
shape = 22, #square
alpha = 0.5,
size = 2.5) +
geom_line(data = preds[!is.na(preds$ma),],
mapping = aes(DATE, ma, group = 3, color = 'MA'),
alpha = 0.8,
size = 1) +
geom_text(mapping = aes(DATE, pred_sales, label = formatC(pred_sales / 1000, format = 'd', big.mark = ',')),
angle = 90,
size = 2.75,
hjust = 1.25,
vjust = 0.4) +
labs(title = sprintf('%s Sales Predictions - %s', 'Overall', format(FM, '%b %Y')),
x = 'Date',
y = 'Volume in MMlbs') +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1, size = 8),
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank(),
legend.title = element_blank(),
legend.position = 'bottom',
legend.text = element_text(size = 8),
legend.margin = margin(t = 0.25, unit = 'cm')) +
scale_x_date(breaks = x.ticks,
date_labels = '%b %e',
limits = x.range) +
scale_y_continuous(limits = c(0, y.max),
labels = function(x) { formatC(x / 1000, format='d', big.mark=',') }) +
scale_color_manual(values = line.cols,
breaks = c('MA'),
labels = c(MA = 'Mvg Avg (5)')) +
scale_fill_manual(values = fill.cols,
breaks = c('P', 'O', 'S'),
labels = c(O = 'Open Orders', S = 'Sales', P = 'Predictions'))
p
The chart it generates is this:
As you can see, the legend does a couple of funky things. It's close, but not quite there. I only want boxes with exterior borders for Predictions, Open Orders, and Sales, and only a blue line for the Mvg Avg (5).
Any advice would be appreciated.
Thanks!
Rather late, but if you are still interested to understand this problem, the following should work. Explanations are included as comments within the code:
library(dplyr)
preds %>%
# scale the values for ALL numeric columns in the dataset, before
# passing the dataset to ggplot()
mutate_if(is.numeric, ~./1000) %>%
# since x / y mappings are stated in the top level ggplot(), there's
# no need to repeat them in the subsequent layers UNLESS you want to
# override them
ggplot(mapping = aes(x = DATE, y = pred_sales)) +
# 1. use data = . to inherit the top level data frame, & modify it on
# the fly for this layer; this is neater as you are essentially
# using a single data source for the ggplot object.
# 2. geom_col() is a more succinct way to say geom_bar(stat = "identity")
# (I'm using tidyr rather than reshape package, since ggplot2 is a
# part of the tidyverse packages, & the two play together nicely)
geom_col(data = . %>%
select(S, O, DATE) %>%
tidyr::gather(variable, value, -DATE),
aes(y = value, fill = variable, color = variable),
width = 1, alpha = 0.5) +
# don't show legend for this layer (o/w the fill / color legend would
# include a square shape in the centre of each legend key)
geom_point(aes(fill = 'P', color = 'P'),
shape = 22, alpha = 0.5, size = 2.5, show.legend = FALSE) +
# use data = . %>% ... as above.
# since the fill / color aesthetic mappings from the geom_col layer would
# result in a border around all fill / color legends, avoid it all together
# here by hard coding the line color to "blue", & map its linetype instead
# to create a separate linetype-based legend later.
geom_line(data = . %>% na.omit(),
aes(y = ma, linetype = 'MA'),
color = "blue", alpha = 0.8, size = 1) +
# scales::comma is a more succinct alternative to formatC for this use case
geom_text(aes(label = scales::comma(pred_sales)),
angle = 90, size = 2.75, hjust = 1.25, vjust = 0.4) +
labs(title = sprintf('%s Sales Predictions - %s', 'Overall', format(FM, '%b %Y')),
x = 'Date',
y = 'Volume in MMlbs') +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1, size = 8),
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank(),
legend.title = element_blank(),
legend.position = 'bottom',
legend.text = element_text(size = 8),
legend.margin = margin(t = 0.25, unit = 'cm')) +
scale_x_date(breaks = x.ticks,
date_labels = '%b %e',
limits = x.range) +
# as above, scales::comma is more succinct
scale_y_continuous(limits = c(0, y.max / 1000),
labels = scales::comma) +
# specify the same breaks & labels for the manual fill / color scales, so that
# a single legend is created for both
scale_color_manual(values = line.cols,
breaks = c('P', 'O', 'S'),
labels = c(O = 'Open Orders', S = 'Sales', P = 'Predictions')) +
scale_fill_manual(values = fill.cols,
breaks = c('P', 'O', 'S'),
labels = c(O = 'Open Orders', S = 'Sales', P = 'Predictions')) +
# create a separate line-only legend using the linetype mapping, with
# value = 1 (i.e. unbroken line) & specified alpha / color to match the
# geom_line layer
scale_linetype_manual(values = 1,
label = 'Mvg Avg (5)',
guide = guide_legend(override.aes = list(alpha = 1,
color = "blue")))

Resources