R ggplot mixed legend of two legends - r

Here is the graph that I have as a basis:
color_two_groups_type_2 <- c("dark red", "black")
pd <- position_dodge(0.4)
hedonic_price_indices %>% ggplot(aes(x=year, y=index, group=factor(sample_sizes), color=factor(sample_sizes))) +
geom_line(linetype = "dashed", position = pd) +
geom_point(size = 0.5, position = pd) +
geom_errorbar(aes(ymin = index_lower_ci, ymax = index_upper_ci), width = 0.15, size = 0.25, colour="black", position = pd) +scale_y_continuous(breaks = c(0.5,1.0,1.5,2.0,2.5), limits = c(0.125, 2.85)) +
theme(legend.position="bottom", legend.margin=margin(0,0,0,0), legend.box.margin=margin(-20,0,0,0)) +
scale_color_manual(labels = c("Alternative", "Normal"), values = color_two_groups_type_2, guide = guide_legend(reverse = TRUE)) +
labs(title = "", x = "", y = "Index value (2000 = 1)", color = "") +
scale_x_discrete(breaks = c(1985,1990,1995,2000,2005,2010,2015,2020))
Now I would like to have two different line types.
desired_linetype <- c("dotted", "solid")
color_two_groups_type_2 <- c("dark red", "black")
pd <- position_dodge(0.4)
hedonic_price_indices %>% ggplot(aes(x=year, y=index, group=factor(sample_sizes), color=factor(sample_sizes))) +
#geom_line(linetype = "dashed", position = pd) +
geom_line(aes(linetype = sample_sizes), position = pd) +
scale_linetype_manual(values = desired_linetype) +
geom_point(size = 0.5, position = pd) +
geom_errorbar(aes(ymin = index_lower_ci, ymax = index_upper_ci), width = 0.15, size = 0.25, colour="black", position = pd) +
scale_y_continuous(breaks = c(0.5,1.0,1.5,2.0,2.5), limits = c(0.125, 2.85)) + theme(legend.position="bottom", legend.margin=margin(0,0,0,0), legend.box.margin=margin(-20,0,0,0)) +
scale_color_manual(labels = c("Alternative", "Normal"), values = color_two_groups_type_2, guide = guide_legend(reverse = TRUE)) +
labs(title = "", x = "", y = "Index value (2000 = 1)", color = "") +
scale_x_discrete(breaks = c(1985,1990,1995,2000,2005,2010,2015,2020))
Unfortunately, I have got two legends by now. By adding + guides(col = "none") (e.g. at the bottom), the left part of the legend gets removed:
And alternatively, by changing scale_linetype_manual(values = desired_linetype) to scale_linetype_manual(values = desired_linetype, guide="none"), the right part of the legend is gets removed:
However, I would like to have mixed version of these two legends. I.e. a legend that shows both the line type and the color. How could I obtain this result? (and I would prefer not to have a legend title ("sample sizes"), as in my initial graph).
I would be thankful for any suggestion!
Here is some code to reproduce the graphs:
hedonic_price_indices <- structure(list(estimate = c(-0.575412358998748, -0.52549627191954, -0.48635414326085, -0.732792998304216, -0.562889873546058, -0.913572700671539, -1.13936126077503, -1.08231133221031, -1.3515171997382, -0.94983790292841 ), lower_ci = c(-0.626714841953077, -0.584959417015897, -0.542829387483941, -0.790953736050918, -0.620938372048851, -1.02481824744291, -1.26017870739697, -1.17246349249945, -1.41331442736626, -1.01254016013769), upper_ci = c(-0.524109876044418, -0.466033126823183, -0.429878899037759, -0.674632260557514, -0.504841375043265, -0.802327153900171, -1.01854381415308, -0.992159171921177, -1.28971997211013, -0.887135645719133), year = c("1984", "1985", "1986", "1987", "1988", "1984", "1985", "1986", "1987", "1988"), estimate_exp = c(-0.437527119774759, -0.408738135115574, -0.38513598119696, -0.519435103003286, -0.430439275221177, -0.598911308640654, -0.679976631974547, -0.661188486027214, -0.741152760388594, -0.613196281876959), lower_ci_exp = c(-0.465655673667104, -0.442871528710716, -0.41889823785973, -0.546587846514592, -0.462560117662101, -0.641138316492387, -0.71639666004378, -0.69039670436256, -0.756664572496545, -0.636705020910341 ), upper_ci_exp = c(-0.407917843611993, -0.372513502931199, -0.349412123229172, -0.490656308062782, -0.3963986859341, -0.551715477774212, -0.63887958407625, -0.629224741409214, -0.724652122619944, -0.588166297456909), index = c(0.562472880225241, 0.591261864884426, 0.61486401880304, 0.480564896996714, 0.569560724778823, 0.401088691359346, 0.320023368025453, 0.338811513972786, 0.258847239611406, 0.386803718123041), index_lower_ci = c(0.534344326332896, 0.557128471289284, 0.58110176214027, 0.453412153485408, 0.537439882337899, 0.358861683507613, 0.28360333995622, 0.30960329563744, 0.243335427503455, 0.363294979089659), index_upper_ci = c(0.592082156388007, 0.627486497068801, 0.650587876770828, 0.509343691937218, 0.6036013140659, 0.448284522225788, 0.36112041592375, 0.370775258590786, 0.275347877380056, 0.411833702543091), sample_sizes = c("Normal", "Normal", "Normal", "Normal", "Normal", "Alternative", "Alternative", "Alternative", "Alternative", "Alternative")), row.names = c("normal_sale_1984", "normal_sale_1985", "normal_sale_1986", "normal_sale_1987", "normal_sale_1988", "foreclosure_1984", "foreclosure_1985", "foreclosure_1986", "foreclosure_1987", "foreclosure_1988"), class = "data.frame")

To merge your legends use the same labels and guide in both scale_color and scale_linetype and the same name in labs:
library(ggplot2)
library(dplyr)
desired_linetype <- c("dotted", "solid")
color_two_groups_type_2 <- c("dark red", "black")
pd <- position_dodge(0.4)
hedonic_price_indices %>%
ggplot(aes(x = year, y = index, group = factor(sample_sizes), color = factor(sample_sizes))) +
geom_line(aes(linetype = sample_sizes), position = pd) +
geom_point(size = 0.5, position = pd) +
geom_errorbar(aes(ymin = index_lower_ci, ymax = index_upper_ci),
width = 0.15, size = 0.25, colour = "black", position = pd
) +
scale_x_discrete(breaks = c(1985, 1990, 1995, 2000, 2005, 2010, 2015, 2020)) +
scale_y_continuous(breaks = c(0.5, 1.0, 1.5, 2.0, 2.5), limits = c(0.125, 2.85)) +
scale_color_manual(
labels = c("Alternative", "Normal"),
values = color_two_groups_type_2,
guide = guide_legend(reverse = TRUE)
) +
scale_linetype_manual(
labels = c("Alternative", "Normal"),
values = desired_linetype,
guide = guide_legend(reverse = TRUE)
) +
labs(
title = "", x = "", y = "Index value (2000 = 1)",
color = "", linetype = ""
) +
theme(
legend.position = "bottom",
legend.margin = margin(0, 0, 0, 0),
legend.box.margin = margin(-20, 0, 0, 0)
)

Related

Apply color gradient to axis lines in connected scatterplot

OK, I have code to generate a connected scatterplot, and I would like to have a color gradient along the bottom and left edges of the chart area, and I need the viewable portion of the gradient to be based on the values contained in the chart (the values the gradient is based on is static).
Adding lines with the proper weight in the location I need to the chart is no problem, and I can specify a single color for the line (as seen for the y axis), but when I attempt to apply a gradient to the line using scale_colour_gradientn() it doesn't do anything (the provided code is attempting to apply the gradient to the line on the bottom of the chart).
If there's a way to capture the limits of x & y as rendered by the chart (not the min & max values displayed, as the label locations will exceed them), I could make something work using other ggplot features, but it doesn't appear those are knowable values.
sample code:
parent <- c('A','A','A','B','B','B','C','C','C')
pd_identifier <- c('2021_10','2022_03','2022_08','2021_10','2022_03','2022_08','2021_10','2022_03','2022_08')
PtChg <- c(-15.3,-19.4,-16.0,-9.83,-11.9,-13.4,0.876,2.10 ,2.24)
Impact <- c(-0.684 ,-0.860 ,-0.558 ,-1.55 ,-2.00 ,-2.68 ,-0.165 ,-0.0730,-0.0816)
label <- c(NA,'A',NA,NA,NA,'B',NA,NA,'C')
nudge_x <- c(NA,-0.984,NA,NA,NA,-0.400,NA,NA,0.944)
nudge_y <- c(NA,0.0352,NA,NA,NA,-0.183,NA,NA,0.0659)
df <- as.data.frame(cbind(parent,pd_identifier,label,PtChg,Impact,nudge_x,nudge_y))
df[, 4:ncol(df)] <- lapply(4:ncol(df), function(x) as.numeric(df[[x]]))
ggplot(df, aes(PtChg, Impact)) +
theme_bw() +
theme(plot.title = element_text(hjust = 0.5),
panel.grid = element_line(linetype = "dashed",colour = "#D3D3D3")) +
scale_colour_gradientn(
colors=c("#C00000","#C00000","#FFFF00","#00B050","#00B050"),
values=c(0,0.425,0.5,0.575,1)) +
theme(axis.line.x.bottom = element_line(color = (PtChg + 100)/200,size = 4)) +
theme(axis.line.y.left = element_line(color = "#D3D3D3",size = 4)) +
geom_vline(aes(xintercept = 0),size = 1,colour = "#D3D3D3") +
geom_hline(aes(yintercept = 0),size = 1,colour = "#D3D3D3") +
geom_path(aes(group=parent),
colour="#E20074",
arrow = arrow(length=unit(0.3,"cm"),
ends="last",
type = "closed")) +
geom_text_repel(data = df,
aes(label = label),
min.segment.length = 0.1,
nudge_x = df$nudge_x,
nudge_y = df$nudge_y,
direction = "both",
force = 100,
force_pull = 1,
max.time = 500,
max.iter = 1000000,
# verbose = TRUE,
na.rm = TRUE
)
SOLUTION:
Final code for ggplot (and calculating boundaries):
x_min = if((floor(min(df$PtChg)/5)*5 - min(df$PtChg)) >= 2.5)
{floor(min(df$PtChg)/5)*5} else {floor(min(df$PtChg)/5)*5 - 2.5}
x_max = if((ceiling(max(df$PtChg)/5)*5 - max(df$PtChg)) >= 2.5)
{ceiling(max(df$PtChg)/5)*5} else {ceiling(max(df$PtChg)/5)*5 + 2.5}
y_min = if((floor(min(df$Impact)/.5)*.5 - min(df$Impact)) >= 0.25)
{floor(min(df$Impact)/.5)*.5} else {floor(min(df$Impact)/.5)*.5 - 0.25}
y_max = if((ceiling(max(df$Impact)/.5)*.5 - max(df$Impact)) >= 2.5)
{ceiling(max(df$Impact)/.5)*.5} else {ceiling(max(df$Impact)/.5)*.5 + 0.25}
ggplot(df, aes(PtChg, Impact)) +
theme_bw() +
theme(plot.title = element_text(hjust = 0.5),
panel.grid = element_line(linetype = "dashed",colour = "#D3D3D3")) +
geom_vline(aes(xintercept = 0),size = 1,colour = "#D3D3D3") +
geom_hline(aes(yintercept = 0),size = 1,colour = "#D3D3D3") +
geom_path(aes(group=parent),
colour="#E20074",
arrow = arrow(length=unit(0.3,"cm"),
ends="last",
type = "closed")) +
geom_text_repel(data = df,
aes(label = label),
min.segment.length = 0.1,
nudge_x = df$nudge_x,
nudge_y = df$nudge_y,
direction = "both",
force = 100,
force_pull = 1,
max.time = 500,
max.iter = 1000000,
na.rm = TRUE
) +
ggforce::geom_link2(data = data.frame(PtChg = seq(-100,100), Impact = y_min),
aes(color = (PtChg+100)/200), size = 8) +
theme(axis.line.x = element_blank()) +
scale_colour_gradientn(
colors = c("#C00000","#C00000","#FFFF00","#00B050","#00B050"),
values = c(0,0.425,0.5,0.575,1), guide = "none") +
new_scale_color() +
ggforce::geom_link2(data = data.frame(PtChg = x_min,Impact = seq(-10,10)),
aes(color = (Impact+10)/20), size = 8) +
theme(axis.line.y = element_blank()) +
scale_colour_gradientn(
colors = c("#C00000","#C00000","#FFFF00","#00B050","#00B050"),
values=c(0,0.45,0,0.55,1), guide = "none") +
coord_cartesian(xlim = c(x_min,x_max),ylim = c(y_min,y_max), expand = FALSE)
so it looks like this:
You can specify the exact limits of your plot with coord_cartesian, which allows you to draw a gradient line exactly along the x axis, for example with geom_link2 from ggforce
ggplot(df, aes(PtChg, Impact)) +
theme_bw() +
theme(plot.title = element_text(hjust = 0.5),
panel.grid = element_line(linetype = "dashed",colour = "#D3D3D3")) +
scale_colour_gradientn(
colors = c("#C00000","#C00000","#FFFF00","#00B050","#00B050"),
values = c(0,0.425,0.5,0.575,1), guide = "none") +
geom_vline(aes(xintercept = 0),size = 1,colour = "#D3D3D3") +
geom_hline(aes(yintercept = 0),size = 1,colour = "#D3D3D3") +
geom_path(aes(group=parent),
colour="#E20074",
arrow = arrow(length=unit(0.3,"cm"),
ends="last",
type = "closed")) +
coord_cartesian(ylim = c(-2.75, 0.1), expand = FALSE) +
geom_text_repel(data = df,
aes(label = label),
min.segment.length = 0.1,
nudge_x = df$nudge_x,
nudge_y = df$nudge_y,
direction = "both",
force = 100,
force_pull = 1,
max.time = 500,
max.iter = 1000000,
na.rm = TRUE
) +
ggforce::geom_link2(data = data.frame(PtChg = seq(-20, 5), Impact = -2.75),
aes(color = PtChg), linewidth = 8) +
theme(axis.line.x = element_blank())

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")

ggplot2 scale_color_identity() how to change linestyle and design of the legend?

I coded the following ggplot. The problem is that the design of the legend is flawed: The elements of the legend are interconnected with what appears to be dashed lines. How can this be removed? And furthermore, navy should be a dashed line, but it is shown as a solid one. Is there a possibility to change that? This is my code:
plot1 <- ggplot() +
geom_line(aes(x = datacom$Datum , y = datacom$`CDU/CSU`, colour = "black"),size=0.8) +
geom_line(aes(x = datacom$Datum , y = datacom$SPD, colour = "red"),size=0.8) +
geom_line(aes(x = datacom$Datum , y = datacom$GRÜNE, col = "green"),size=0.8) +
geom_line(aes(x = datacom$Datum , y = datacom$FDP, col = "gold1"),size=0.8) +
geom_line(aes(x = datacom$Datum , y = datacom$`Linke/PDS`, col = "darkred"),size=0.8) +
geom_line(aes(x = datacom$Datum[154:168] , y = datacom$Piraten[154:168], col = "tan1"),size=0.8) +
geom_line(aes(x = datacom$Datum[169:272] , y = datacom$AfD[169:272], col = "blue"),size=0.8) +
geom_line(aes(x = datacom$Datum , y = datacom$Sonstige, col = "grey"),size=0.8) +
geom_vline(aes(xintercept = datacom$Datum[263], color = "navy"), linetype="longdash",size = 0.5)+
geom_vline(xintercept = datacom$Datum[215], color = "navy", size = 0.5,linetype="longdash")+
geom_vline(xintercept = datacom$Datum[167], color = "navy", size = 0.5,linetype="longdash")+
geom_vline(xintercept = datacom$Datum[127], color = "navy", size = 0.5,linetype="longdash")+
geom_vline(xintercept = datacom$Datum[79], color = "navy", size = 0.5,linetype="longdash")+
geom_vline(xintercept = datacom$Datum[44], color = "navy", size = 0.5,linetype="longdash")+
scale_color_identity(name = NULL, labels = c(black = "CDU/CSU", red = "SPD",green="Die Grünen",gold1="FDP",darkred = "Die Linke/PDS",tan1="Piraten",blue="AfD",grey="Sonstige",navy="Bundestagswahlen"), guide = "legend") +
theme_bw() +
theme(legend.position = "bottom") +
theme(axis.text.x = element_text(angle = 90)) +
labs(title="Forsa-Sonntagsfrage Bundestagswahl in %")+ylab("Prozent")+xlab("Jahre")
plot1
Thanks in advance
Your code has a lot of unnecessary repetition and you are not taking advantage of the syntax of ggplot.
The reason for the vertical dashed lines in the legend is that one of your geom_vline calls includes a color mapping, so its draw key is being added to the legend. You can change its key_glyph to draw_key_path to fix this. Note that you only need a single geom_vline call, since you can have multiple x intercepts.
ggplot(datacom, aes(x = Datum)) +
geom_line(aes(y = `CDU/CSU`, colour = "black"), size = 0.8) +
geom_line(aes(y = SPD, colour = "red"), size = 0.8) +
geom_line(aes(y = GRÜNE, col = "green"), size = 0.8) +
geom_line(aes(y = FDP, col = "gold1"), size = 0.8) +
geom_line(aes(y = `Linke/PDS`, col = "darkred"),size = 0.8) +
geom_line(aes(y = Piraten, col = "tan1"),
data = datacom[154:168,], size = 0.8) +
geom_line(aes(y = AfD, col = "blue"),
data = datacom[169:272,], size = 0.8) +
geom_line(aes(y = Sonstige, col = "grey"), size = 0.8) +
geom_vline(data = datacom[c(263, 215, 167, 127, 79, 44),],
aes(xintercept = Datum, color = "navy"), linetype = "longdash",
size = 0.5, key_glyph = draw_key_path)+
scale_color_identity(name = NULL,
labels = c(black = "CDU/CSU", red = "SPD",
green = "Die Grünen", gold1 = "FDP",
darkred = "Die Linke/PDS",
tan1 = "Piraten", blue = "AfD",
grey = "Sonstige",
navy = "Bundestagswahlen"),
guide = "legend") +
theme_bw() +
theme(legend.position = "bottom",
axis.text.x = element_text(angle = 90)) +
labs(title = "Forsa-Sonntagsfrage Bundestagswahl in %",
y = "Prozent",
x = "Jahre")
An even better way to make your plot would be to pivot the data into long format. This would mean only a single geom_line call:
library(tidyverse)
datacom %>%
mutate(Piraten = c(rep(NA, 153), Piraten[154:168],
rep(NA, nrow(datacom) - 168)),
AfD = c(rep(NA, 168), AfD[169:272],
rep(NA, nrow(datacom) - 272))) %>%
pivot_longer(-Datum, names_to = "Series") %>%
ggplot(aes(x = Datum, y = value, color = Series)) +
geom_line(size = 0.8, na.rm = TRUE) +
geom_vline(data = datacom[c(263, 215, 167, 127, 79, 44),],
aes(xintercept = Datum, color = "Bundestagswahlen"),
linetype = "longdash", size = 0.5, key_glyph = draw_key_path) +
scale_color_manual(name = NULL,
values = c("CDU/CSU" = "black", SPD = "red",
"GRÜNE" = "green", FDP = "gold1",
"Linke/PDS" = "darkred",
Piraten = "tan1", AfD = "blue",
Sonstige = "grey",
"Bundestagswahlen" = "navy")) +
theme_bw() +
theme(legend.position = "bottom",
axis.text.x = element_text(angle = 90)) +
labs(title = "Forsa-Sonntagsfrage Bundestagswahl in %",
y = "Prozent",
x = "Jahre")
Data used to create plot
Obviously, I had to create some data to get your code to run, since you didn't supply any. Here is my code for creating the data
var <- seq(5, 15, length = 280)
datacom <- data.frame(Datum = seq(as.POSIXct("1999-01-01"),
as.POSIXct("2022-04-01"), by = "month"),
`CDU/CSU` = 40 + cumsum(rnorm(280)),
SPD = 40 + cumsum(rnorm(280)),
GRÜNE = rpois(280, var),
FDP = rpois(280, var),
`Linke/PDS` = rpois(280, var),
Piraten = rpois(280, var),
AfD = rpois(280, var),
Sonstige = rpois(280, var), check.names = FALSE)

How to type subscripts in geom_text labels in ggplot

I have timeseries data plotted and separated by timepoints that I'd like to label with subscripts. Below is the code I'm using to generate the figure and timepoint labels. I'd like for the -1, 3 and 6 to be subscripts. Thanks in advance!
timepoints=data.frame(date=as_datetime(c("2016-08-15" ,"2016-11-22",
"2017-02-25")), timepoint=c("T-1", "T3", "T6"))
TimeseriespH = ggplot(FinalSeaphox, aes(x=DTTM)) +
geom_line(aes(y=MpH, color = "Outer Bay", group = grp), size = 0.5) +
geom_line(aes(y=CpH, color = "Inner Bay", group = grp), size = 0.5) +
scale_x_datetime(labels = date_format("%b '%y"), date_breaks = "1
month", limits = as_datetime(c("2016-07-01","2017-04-19"))) +
labs(x = "", y = "pH") +
scale_y_continuous(limits = c(7.4,8.2)) +
geom_vline(xintercept = as_datetime("2016-12-01"), linetype = 2, color
= "black") +
geom_vline(xintercept = as_datetime("2016-08-26"), linetype = 2, color
= "black") +
geom_vline(xintercept = as_datetime("2017-03-06"), linetype = 2, color
= "black") +
geom_text(data=timepoints, mapping=aes(x=date, y=c(8.18, 8.18, 8.18),
label=timepoint), size=5, vjust=-0.4, hjust=0, inherit.aes = FALSE,
color = "black")
For the subscripts, you need to enclose between brackets:
timepoint = c("T[-1]", "T[3]", "T[6]")
Then use parse = TRUE in geom_text:
library(ggplot2)
library(lubridate)
timepoints=data.frame(
date = as_datetime(c("2016-08-15" ,"2016-11-22", "2017-02-25")),
Y = c(8, 8.1, 8)
timepoint = c("T[-1]", "T[3]", "T[6]")
)
ggplot(timepoints) +
geom_point(aes(x = date, y=Y), size = 3) +
geom_text(data=timepoints,
mapping=aes(x=date, y=c(8.18, 8.18, 8.18),
label = timepoint),
size=5, vjust=0.4, hjust=0, inherit.aes = FALSE,
color = "black", parse = TRUE)

waterfall chart in ggplot2 doesnt seem to render right

I am trying to recreate the waterfall chart as shown in
https://vita.had.co.nz/papers/ggplot2-wires.pdf
I am reproducing the code from the link
balance <- data.frame(event = c("Starting\nCash", "Sales", "Refunds",
"Payouts", "Court\nLosses", "Court\nWins", "Contracts", "End\nCash"),
change = c(2000, 3400, -1100, -100, -6600, 3800, 1400, -2800))
balance$balance <- cumsum(c(0, balance$change[-nrow(balance)]))
balance$time <- 1:nrow(balance)
balance$flow <- factor(sign(balance$change))
ggplot(balance) +
geom_hline(yintercept = 0, colour = "white", size = 2) +
geom_rect(aes(fill= 'red'),xmin = time - 0.45, xmax = time + 0.45, ymin = balance, ymax = balance)
geom_text(aes(x = time, y = pmin(balance, balance + change) - 50, label = dollar(change)),
hjust = 0.5, vjust = 1, size = 3)
scale_x_continuous( breaks = balance$time, labels = balance$event) +
scale_y_continuous("Balance") +
scale_fill_manual(values = c("-1" = "red", "1" = "black"))
it throws an error :Error in scale_x_continuous(breaks = balance$time, labels = balance$event) + : non-numeric argument to binary operator
THe final output, per the pdf should look like the image below
ggplot(balance %>%
mutate(flow = factor(flow, labels = c("Negative", "Positive")))) +
geom_hline(yintercept = 0, colour = "white", size = 2) +
geom_rect(aes(fill= flow, xmin = time - 0.45, xmax = time+0.45, ymin = change, ymax = balance),
color = "black") +
geom_text(aes(x = time, y = pmin(balance, balance + change) - 50, label = change),
hjust = 0.5, vjust = 1, size = 3) +
scale_x_continuous(breaks = balance$time, labels = balance$event) +
scale_y_continuous("Balance") +
scale_fill_manual(values = c("Negative" = "red", "Positive" = "green"))

Resources