Adding date labels to barplot - r

I'm trying to add date labels to each individual bar that i've plotted. The data looks like this:
structure(list(lakeID = c("WE1", "WE1", "WE1", "WE1", "WE1",
"WE1", "WE1", "WE1", "WE1", "WE1"), depth = c("hypolimnion",
"hypolimnion", "hypolimnion", "hypolimnion", "hypolimnion", "hypolimnion",
"hypolimnion", "hypolimnion", "hypolimnion", "hypolimnion"),
date = structure(c(1505779200, 1529366400, 1534723200, 1537142400,
1559088000, 1590624000, 1592352000, 1596153600, 1597881600,
1599696000), class = c("POSIXct", "POSIXt"), tzone = "UTC"),
year = c(2017L, 2018L, 2018L, 2018L, 2019L, 2020L, 2020L,
2020L, 2020L, 2020L), BACI = c("Control", "Control", "Control",
"Control", "Impact", "Impact", "Impact", "Impact", "Impact",
"Impact"), N = c(2L, 2L, 1L, 1L, 7L, 56L, 10L, 58L, 3L, 2L
), meanlengths = c(1.44092870850016, 1.90413253399558, 2.08356379729054,
1.24630120343851, 6.39410976055929, 6.07576588787627, 5.63215818993585,
6.00116183368038, 5.42957068546558, 3.62096915399567), sd = c(0.261562571663927,
0.237860661401758, NA, NA, 0.454442531596122, 0.703831022329251,
0.465831548164042, 1.1448481521142, 1.19135665831808, 1.41507359493585
), SE = c(0.184952668128155, 0.1681928866547, NA, NA, 0.171763131967707,
0.0940533765621035, 0.14730886981608, 0.150325927020161,
0.687830087380796, 1.00060813485716), Upper2SE = c(1.80343593803135,
2.23379059183879, NA, NA, 6.73076549921599, 6.26011050593799,
5.92088357477536, 6.2958006506399, 6.77771765673194, 5.58216109831572
), Lower2SE = c(1.07842147896898, 1.57447447615237, NA, NA,
6.05745402190258, 5.89142126981455, 5.34343280509633, 5.70652301672087,
4.08142371419922, 1.65977720967563)), row.names = 22:31, class = "data.frame")
I've attempted to plot the dates with this code but have not been able to get them to show:
xxx <- barplot(ChiSum$meanlength, axisnames=TRUE, beside = TRUE, names.arg=c(ChiSum$date), col=ifelse(ChiSum$BACI=="Control",'white','gray'), ylim = c(-0.01,8), ylab = "Mean body length",
xlab="Date",xaxt="n")
arrows(xxx,ChiSum$Lower2SE,xxx,ChiSum$Upper2SE, code=3, length=0.02, angle = 90,
col=ifelse(ChiSum$BACI=="Control",'black','black'))
axis(side=1,at=XXX[c(1,20)], labels=format(ChiSum$date))

How about this:
bar_mids <- cumsum(c(.7, rep(1.2,9)))
par(mar=c(8,4,2,1)+.1)
xxx <- barplot(ChiSum$meanlength, axisnames=TRUE, beside = TRUE, names.arg=c(ChiSum$date), col=ifelse(ChiSum$BACI=="Control",'white','gray'), ylim = c(-0.01,8), ylab = "Mean body length",
xlab="",xaxt="n")
arrows(xxx,ChiSum$Lower2SE,xxx,ChiSum$Upper2SE, code=3, length=0.02, angle = 90,
col=ifelse(ChiSum$BACI=="Control",'black','black'))
axis(side=1,at=bar_mids, labels=format(ChiSum$date), las=2)
The key is to know where the mid-points of the bars are. The default settings are that the bars are one-unit wide with a space (before every bar) of 0.2. So the mid-point of the first bar is at 0.7. The mid-point of the second bar is 0.7 + 1.2, the mid-point of the third is 0.7 + 1.2*2, etc... These mid-points should be specified as at and then you can use the dates as the labels. To make them plot nicely, you can use las=2 to turn the labels perpendicular to the axis.
You could also do it with ggplot2:
ChiSum %>%
arrange(date) %>%
mutate(obs = 1:n()) %>%
ggplot(aes(x=obs, y=meanlengths, ymin = Lower2SE, ymax=Upper2SE, fill=BACI)) +
geom_bar(stat="identity", col="black") +
geom_errorbar(width=.15) +
scale_x_continuous(breaks=1:10, labels=ChiSum$date) +
theme_classic() +
theme(axis.text.x = element_text(angle=45, hjust=1),
legend.position = c(.15, .85)) +
labs(x="", y="Mean Length") +
scale_fill_manual(values=c("white", "gray50"))

Related

Adding line with specific df value to each bar in ggplot

My df is organized this way for example:
OCCURED_COUNTRY_DESC | a | b | c | d | flagged | type | MedDRA_PT| **E** |
__________________________________________________________________________
UNITED STATES |403|1243|473|4077| yes | disp | Seizure |144.208|
__________________________________________________________________________
My data:
structure(list(OCCURED_COUNTRY_DESC = c("AUSTRALIA", "AUSTRIA",
"BELGIUM", "BRAZIL", "CANADA"), a = c(4L, 7L, 20L, 5L, 11L),
b = c(31, 27, 100, 51, 125), c = c(872, 869, 856, 871, 865
), d = c(5289, 5293, 5220, 5269, 5195), w = c(876, 876, 876,
876, 876), x = c(5320, 5320, 5320, 5320, 5320), y = c(35L,
34L, 120L, 56L, 136L), z = c(6161, 6162, 6076, 6140, 6060
), N = c(6196, 6196, 6196, 6196, 6196), k = c("0.5", "0.5",
"0.5", "0.5", "0.5"), SOR = c(0.80199821407511, 1.52042360060514,
1.21312776329214, 0.615857869962066, 0.539569644832803),
log = c(-0.318329070860348, 0.604473324558599, 0.278731499148795,
-0.699330656240263, -0.890118907611227), LL99 = c(-0.695969674426877,
0.382102954188229, 0.198127619344382, -1.00534117464748,
-1.03425468471322), UL99 = c(-0.0544058884186467, 0.763880731966007,
0.337239065783058, -0.482651467660248, -0.785935460582379
), flagged = c("no", "no", "no", "no", "yes"), type = c(NA,
NA, NA, NA, "under"), MedDRA_PT = c("Seizure", "Seizure",
"Seizure", "Seizure", "Seizure"), E = c(5.11098506333901,
4.43283582089552, 16.3984674329502, 8.43063199848168, 20.8132820019249
)), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame"
))
I am using ggplot2 to create a bar chart using the following piece of code:
test2 %>% #using test2 as the df
ggplot(aes(a, OCCURED_COUNTRY_DESC, fill=type)) +
geom_bar(stat="identity")+
scale_fill_manual(values = c("disp" = "#FF8C00",
"under" = "#7EC0EE",
"NA"="#EEE9E9"))+
theme_classic()+
labs(title = "Seizure",
x = "Count",
y = "")
What I would like to do is to add a black line in each bar correspondent to the E value, from the dataframe, for that country. However I haven't been successful. Can someone kindly guide me on how to achieve this?
Thanks!
One option to achieve your desired result would be via a geom_segment, where you map your E column on both the x and the xend position. "Tricky" part are the y positions. However, as a categorical axis is still a numeric axis we could add a helper column to your data which contains the numeric positions of your categorical OCCURED_COUNTRY_DESC column. This helper column could then be mapped on the y and the yend aes needed by geom_segment where we also take into account the width of the bars:
library(ggplot2)
test2$OCCURED_COUNTRY_DESC_num <- as.numeric(factor(test2$OCCURED_COUNTRY_DESC))
width <- .9 # defautlt width of bars
ggplot(test2, aes(a, OCCURED_COUNTRY_DESC, fill = type)) +
geom_bar(stat = "identity") +
geom_segment(aes(x = E, xend = E,
y = OCCURED_COUNTRY_DESC_num - width / 2,
yend = OCCURED_COUNTRY_DESC_num + width / 2),
color = "black", size = 1) +
scale_fill_manual(values = c(
"disp" = "#FF8C00",
"under" = "#7EC0EE",
"NA" = "#EEE9E9"
)) +
theme_classic() +
labs(
title = "Seizure",
x = "Count",
y = ""
)

R ggplot2 facet_wrap() with scales = "free", but each panel having fixed

I want to produce a figure that will have several scatterplots. Each scatterplot should have its own axis limits, but I want the aspect ratio of each plot to be 1 so that the 1:1 line goes through the plot at a 45 degree angle.
Here's an example of what I have going on:
met <- structure(list(datetime = structure(c(946756800, 946756800, 946756800,946756800, 946756800, 946756800, 946756800, 960465600, 960465600,960465600), class = c("POSIXct", "POSIXt"), tzone = "UTC"), Met_Parameter = c("1/MO l","albedo", "Bowen r", "conv mix h", "mech mix h", "MO l", "sens h flux","wind s", "wstar", "z0"), `Original Met` = c(0.0746268656716418,0.15, 0.8, -999, 24, 13.4, -0.7, 4, 1.2, 1), `Converted Met` = c(-0.0105263157894737,0.15, 0.8, 600, 367, -95, 21.6, 4, 1.2, 1)), row.names = c(1L,2L, 3L, 4L, 5L, 6L, 7L, 1054L, 1055L, 1056L), class = "data.frame")
pOUT <-
ggplot2::ggplot(data = met,
aes(x = `Original Met`,
y = `Converted Met`)) +
ggplot2::geom_point()+
ggplot2::geom_abline(intercept = 0,
slope = 1
) +
ggplot2::facet_wrap("Met_Parameter",
scales = "free") +
ggplot2::ggtitle("Comparison of Original Meteorology Versus Up Over Down Meterology") +
ggplot2::theme_bw()
What I am missing still is how to make the x and y axes fixed within the plot.
Thanks!

ggplot does not find the value that is present in the dataset

I have data as follows:
library(ggplot2)
library(dplyr)
library(tidyverse)
library(ggsignif)
graph <- structure(list(Constraint = structure(c(4L, 2L, 3L, 1L, 5L, 4L,
2L, 3L, 1L, 5L), .Label = c("Major Constraint", "Minor Constraint",
"Moderate Constraint", "No Constraint", "Total"), class = "factor"),
`Observation for Crime = 0` = c(3124, 2484, 3511, 4646, 13765,
3124, 2484, 3511, 4646, 13765), `Observation for Crime = 1` = c(762,
629, 1118, 1677, 4186, 762, 629, 1118, 1677, 4186), `Total Observations` = c(3886,
3113, 4629, 6323, 17951, 3886, 3113, 4629, 6323, 17951),
variable = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L,
2L), .Label = c("Crime = 0", "Crime = 1"), class = "factor"),
value = c(80.3911477097272, 79.79441053646, 75.847915316483,
73.4777795350308, 76.6809648487549, 19.6088522902728, 20.20558946354,
24.152084683517, 26.5222204649692, 23.3190351512451)), row.names = c(NA,
-10L), class = "data.frame")
Constraint Observation for Crime = 0 Observation for Crime = 1 Total Observations variable value
1 No Constraint 3124 762 3886 Crime = 0 80.39115
2 Minor Constraint 2484 629 3113 Crime = 0 79.79441
3 Moderate Constraint 3511 1118 4629 Crime = 0 75.84792
4 Major Constraint 4646 1677 6323 Crime = 0 73.47778
5 Total 13765 4186 17951 Crime = 0 76.68096
6 No Constraint 3124 762 3886 Crime = 1 19.60885
7 Minor Constraint 2484 629 3113 Crime = 1 20.20559
8 Moderate Constraint 3511 1118 4629 Crime = 1 24.15208
9 Major Constraint 4646 1677 6323 Crime = 1 26.52222
10 Total 13765 4186 17951 Crime = 1 23.31904
I am trying to create something like this:
graph %>%
mutate(`Constraint` = fct_relevel(`Constraint`, "No Constraint", "Minor Constraint", "Moderate Constraint", "Major Constraint")) %>%
ggplot(aes(x = `Constraint`, y = value, fill = variable, label=sprintf("%.02f %%", round(value, digits = 1)))) +
geom_col(position = 'dodge') +
geom_text(position = position_dodge(width = .9), # move to center of bars
vjust = -0.5, # nudge above top of bar
size = 4) +
scale_fill_grey(start = 0.8, end = 0.5) +
theme_bw(base_size = 15) +
geom_signif(stat="identity",
data=data.frame(x=c(0.875, 1.875), xend=c(1.125, 2.125),
y=c(5.8, 8.5), annotation=c("**", "NS")),
aes(x=x,xend=xend, y=y, yend=y, annotation=annotation)) +
geom_signif(comparisons=list(c("treatment", "control")), annotations="***",
y_position = 9.3, tip_length = 0, vjust=0.4)
Hoping for an appearance close to the following picture:
But it gives the error that the value is not found, while the value is in the data. Does anyone know what the problem could be?
Include fill and label in geom_col and geom_text -
library(tidyverse)
library(ggsignif)
graph %>%
mutate(`Constraint` = fct_relevel(`Constraint`, "No Constraint", "Minor Constraint", "Moderate Constraint", "Major Constraint")) %>%
ggplot(aes(x = `Constraint`, y = value)) +
geom_col(position = 'dodge', aes(fill = variable)) +
geom_text(position = position_dodge(width = .9), # move to center of bars
aes(label=sprintf("%.02f %%", round(value, digits = 1))),
vjust = -0.5, # nudge above top of bar
size = 4) +
scale_fill_grey(start = 0.8, end = 0.5) +
theme_bw(base_size = 15) +
geom_signif(stat="identity",
data=data.frame(x=c(0.875, 1.875), xend=c(1.125, 2.125),
y=c(5.8, 8.5), annotation=c("**", "NS")),
aes(x=x,xend=xend, y=y, yend=y, annotation=annotation))

How do I label the sum the total of y-axis column values from consecutive bar values like in the example “Confirmed” Cases per x-axis “Date”

I have been working on this for some time, and am re-posting this hoping to simplify the definition of the problem and to bring some clarity from feedback of my previous attempt. I am able to label each individual column value, but not able to put the code together necessary to sum the total. The examples I have looked at never work the way I try to put them together, for example with goup_by, or summarize etc.. I would like to only sum the values of "Confirmed Cases", and not show the other column values as with many c("x", "Y", ... "data"), it becomes impossible to read.
Here is the data frame:
dput(COVID1[1:12, ])
structure(list(COUNTY = c("Antrim", "Antrim", "Antrim", "Charlevoix",
"Charlevoix", "Grand Traverse", "Grand Traverse", "Grand Traverse",
"Antrim", "Grand Traverse", "Grand Traverse", "Grand Traverse"
), Date = structure(c(18453, 18456, 18457, 18453, 18455, 18453,
18456, 18457, 18455, 18453, 18456, 18457), class = "Date"), CASE_STATUS = c("Confirmed",
"Confirmed", "Confirmed", "Confirmed", "Confirmed", "Confirmed",
"Confirmed", "Confirmed", "Probable", "Probable", "Probable",
"Probable"), Cases = c(1L, 1L, 2L, 1L, 3L, 2L, 2L, 1L, 1L, 1L,
1L, 1L)), row.names = c(NA, 12L), class = "data.frame")
Code:
ggplot(filter(COVID1, COUNTY %in% c("Antrim", "Charlevoix", "Grand Traverse"), Cases > 0)) +
geom_col(aes(x = Date, y = Cases, fill = CASE_STATUS), position = position_stack(reverse = TRUE), width = .88)+
geom_text(aes(x = Date, y = Cases, label = (Cases)), position = position_stack(reverse = TRUE), vjust = 1.5, size = 3, color = "white") +
scale_fill_manual(values = c('blue',"tomato"))+
scale_x_date(labels = date_format("%m/%d"), limits = as.Date(c('2020-07-09','today()')), breaks = "1 week")+
theme(axis.text.x = element_text(angle=0))+
labs(title = "Antrim - Grand Traverse - Charlevoix")
I'm not sure if I understood the question but I think you want to add the sum of the confirmed cases as labels. There might be a ggplot way of doing it but I think the most straightforward way is to make another dataset with your labels and feed it in.
date_labels <- filter(COVID1, COUNTY %in% c("Antrim", "Charlevoix", "Grand Traverse"), Cases > 0) %>% group_by(Date) %>% summarise(confirmed_cases = sum(Cases[CASE_STATUS == "Confirmed"]))
ggplot(filter(COVID1, COUNTY %in% c("Antrim", "Charlevoix", "Grand Traverse"), Cases > 0)) +
geom_col(aes(x = Date, y = Cases, fill = CASE_STATUS), position = position_stack(reverse = TRUE), width = .88)+
geom_text(data = date_labels, aes(x = Date, y = 1, label = confirmed_cases), position = position_stack(reverse = TRUE), vjust = 1.5, size = 3, color = "white") +
scale_fill_manual(values = c('blue',"tomato"))+
scale_x_date(labels = label_date("%m/%d"), limits = as.Date(c('2020-07-09','today()')), breaks = "1 week")+
theme(axis.text.x = element_text(angle=0))+
labs(title = "Antrim - Grand Traverse - Charlevoix")
Gives me this result:

ggplot2: change the color of error bars w/o losing customized dodge parameters

I would like to change the color of my error bars to different colors without changing the position of the points on my graph.
Here is a bit of my data:
df <- structure(
list(
yrmonth = structure(
c(
1483228800,
1483228800,
1483228800,
1485907200,
1485907200,
1485907200,
1488326400,
1488326400,
1488326400,
1491004800,
1491004800,
1491004800
),
class = c("POSIXct", "POSIXt"),
tzone = "UTC"
),
index = structure(
c(1L, 3L, 5L, 1L, 3L, 5L, 1L, 3L, 5L, 1L, 3L, 5L),
.Label = c("N-S", "N-S", "E-W", "E-W", "OS"),
class = "factor"
),
N = c(2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1),
GDDLettuce = c(129, 141, 27, 150.5, 209, 87, 247.5,
243, 188, 223, 226.5, 170),
sd = c(
1.4142135623731,
4.24264068711928,
NA,
4.94974746830583,
65.0538238691624,
NA,
12.0208152801713,
8.48528137423857,
NA,
5.65685424949238,
0.707106781186548,
NA
),
se = c(1, 3, NA, 3.5, 46, NA, 8.5, 6, NA, 4, 0.5, NA),
ci = c(
12.7062047361747,
38.1186142085241,
NA,
44.4717165766114,
584.485417864036,
NA,
108.002740257485,
76.2372284170481,
NA,
50.8248189446988,
6.35310236808735,
NA
)
),
.Names = c("yrmonth", "index", "N", "data", "sd", "se", "ci"),
row.names = 31:42,
class = "data.frame"
)
I have my graph set up exactly the way I want it with error bars in the right locations:
ggplot(df, aes(x=yrmonth,y=data,colour=factor(index))) +
geom_line(size=1, position = position_dodge(width = -300000)) + ylim(min(df$data), max(df$data)) +
geom_errorbar(aes(ymin=data-se, ymax=data+se), width = 1000000, size = .5,
position = position_dodge(width = -300000))
When I add one color, the color of the bars change, but it removes all the width and dodge parameters that I put in:
ggplot(df, aes(x=yrmonth,y=data,colour=factor(index))) +
geom_line(size=1, position = position_dodge(width = -300000)) + ylim(min(df$data), max(df$data)) +
geom_errorbar(aes(ymin=data-se, ymax=data+se), colour = "black", width = 1000000, size = .5,
position = position_dodge(width = -300000))
I would like the E-W error bars to be a dark green and the N-S error bars to be a dark red. I would like the lines themselves to stay the same color. Most importantly I want the error bars to stay in there same locations. For some reason, every time I change the color the position of my error bars and lines changes.
A quick and easy solution would be
require(dplyr)
ggplot(df %>% mutate(errorColors = ifelse(index=="N-S","darkred",ifelse(index=="E-W","darkgreen",NA))), aes(x=yrmonth,y=data)) +
geom_line(aes(group=index,color=index),size=1, position = position_dodge(width = -300000)) + ylim(min(df$data), max(df$data)) +
geom_errorbar(aes(ymin=data-se, ymax=data+se,color=errorColors), width = 1000000, size = .5,
position = position_dodge(width = -300000))+scale_color_manual(breaks=c("E-W","N-S","OS"),values=c("darkgreen","darkred","green","red","blue"))
try add one more layer scale_color_manual in your first plot code like this:
ggplot(df, aes(x=yrmonth,y=data,colour=factor(index))) +
geom_line(size=1, position = position_dodge(width = -300000)) + ylim(min(df$data), max(df$data)) +
geom_errorbar(aes(ymin=data-se, ymax=data+se), width = 1000000, size = .5,
position = position_dodge(width = -300000))+
scale_color_manual(values = c('darkblue', 'darkgreen', 'darkred'))

Resources