Axis of a plot with quarters and year - r

Im working with time series given in quarter in R and I want to make a graph as follows:
I have search all over the internet but I haven't get any answer

If you have a time series object like this:
d <- ts(c(265, 280, 288, 280, 278, 292, 298, 282), start = 2016, frequency = 4)
d
#> Qtr1 Qtr2 Qtr3 Qtr4
#> 2016 265 280 288 280
#> 2017 278 292 298 282
Then you could get a reasonable replica of the plot by doing:
library(ggplot2)
data.frame(date = time(d), SALES = d) |>
within(year <- floor(date)) |>
within(Quarter <- paste0("Q", date %% 1 * 4 + 1)) |>
ggplot(aes(interaction(Quarter, year), SALES, group = 1)) +
geom_line(linewidth = 2, color = "#497dba") +
scale_y_continuous("PRICE (millions)", labels = scales::dollar,
breaks = 24:31 * 10, limits = c(240, 310)) +
scale_x_discrete(NULL, labels = ~sub("\\.", "\n", .x)) +
theme_classic(base_size = 20)
Created on 2023-02-19 with reprex v2.0.2

Related

Using ggplot to plot number of TRUE statements from a df

I'm trying to plot a graph where number of TRUE statement from a df column.
I have a df that looks like this
Speed Month_1
12 67
12 114
12 155
12 44
13 77
13 165
13 114
13 177
...
And I would like to plot a bargraph where we have x = Speed and y = Number of rows that are above 100 in Month_1 column.
So for X = 12 I would have a bargraph with a Y-value of 2 and for X = 13 I would have a Y-value of 3.
Can I do this directly in ggplot, or do I have to create a new DF first?
Sure, just filter out the values below 100 in the data you pass to ggplot and do a normal geom_bar
ggplot(df[df$Month_1 >= 100, ], aes(factor(Speed))) +
geom_bar(width = 0.5, fill = 'deepskyblue4') +
theme_bw(base_size = 16) +
labs(x = 'Speed')
If, for some reason, you really need to pass the full data frame without filtering it, you can fill the < 100 values with a fully transparent colour:
ggplot(df, aes(factor(Speed), fill = Month_1 > 100)) +
geom_bar(width = 0.5) +
theme_bw(base_size = 16) +
scale_fill_manual(values = c('#00000000', 'deepskyblue4')) +
labs(x = 'Speed') +
theme(legend.position = 'none')
You can use dplyr to filter your data frame and then plot it with ggplot.
library(tidyverse)
df <- tibble(Speed = c(12, 12, 12, 12, 13, 13, 13, 13),
Month_1 = c(67, 114, 155, 44, 77, 165, 114, 177))
df %>% filter(Month_1 > 100) %>%
ggplot(aes(x = Speed)) + geom_bar()

Getting an error while trying to apply the labels of geom_text to a subset of bars

I want to apply geom_text to a particular set of variables.
I have, for example:
decade count
<dbl> <int>
1 1930 505
2 1940 630
3 1950 806
4 1960 446
5 1970 469
6 1980 807
7 1990 1057
8 2000 1856
9 2010 2133
My plot looks like this:
My plot
So, I want to add some labels to each bar, where the year has to be shown. For the bars with a value of >= 500, I want the label to be inside the bar, for the rest I want it to be outside.
I tried to do this with geom_text:
geom_col(fill = THISBLUE,
width = 0.7) +
geom_text(data = subset(data, count >= 500)
aes(0, y = name, label = name))
However, I get this error message:
Error in count >= 500 : comparison (5) is possible only for atomic and list types
How about this approach?
ggplot(df,aes(decade,count)) +
geom_col(fill = "blue", width = 4) +
coord_flip() +
geom_text(data = subset(df, count >= 500), aes(label = count),nudge_y = -100,color="white") +
geom_text(data = subset(df, count < 500), aes(label = count),nudge_y = 100,color="black")
Input:
df =tribble(
~decade,~count,
1930, 505,
1940, 630,
1950, 806,
1960, 446,
1970, 469,
1980, 807,
1990, 1057,
2000, 1856,
2010, 2133
)

How to set specific date as the beginning date of the year

I want to plot the average annual value of the stream flow data using
WATER YEAR which starts at October and ends at September (say 10/01/1983 to 09/30/1984, this is defined as 1984 water year)
I tried to find solutions elsewhere but I have failed.
Now I'm using the following script to plot the annual average flow
library(tidyverse)
library(lubridate)
library(ggplot2)
#df <- read_csv('dataframe.csv')
df <- df %>%
mutate(date = mdy(df$date))
df <- df %>%
mutate(year = floor_date(date, "year")) %>%
group_by(year) %>%
summarize(avg = mean(flow))
y <- df$avg
x <- as.Date(df$year, format = "Y")
d <- data.frame(x = x, y = y)
# interpolate values from zero to y and create corresponding number of x values
vals <- lapply(d$y, function(y) seq(0, y, by = 0.1))
y <- unlist(vals)
mid <- rep(d$x, lengths(vals))
d2 <- data.frame(x = mid - 100,
xend = mid + 100,
y = y,
yend = y)
ggplot(data = d2, aes(x = x, xend = xend, y = y, yend = yend, color = y)) +
geom_segment(size = 2) +
scale_color_gradient2(low = "midnightblue", mid = "deepskyblue", high = "aquamarine",
midpoint = max(d2$y)/2)+
scale_x_date(date_breaks = "1 year",date_labels = "%Y", expand = c(0,0)) +
theme(axis.text.x = element_text(angle=90, vjust=.5))+
labs(x = "Years", y = "Mean Annual Flow (cms)")+
ggtitle("Mean Annual Flow, Rancho River at ELdorado (1983-2020)")+
theme(plot.title = element_text(hjust = 0.5))
For this I got the following results using calendar year
If I used Water Year there will be no results for 1983
The data frame can be found in the following link
https://drive.google.com/file/d/11PVub9avzMFhUz02cHfceGh9DrlVQDbD/view?usp=sharing
Kindly assist.
If date is superior to 10/01/year(date) it means that this is the next year (in water years):
df %>%
mutate(date=mdy(date), year=year(date), year = year + (date >= mdy(paste0("10/01/", year))))
# A tibble: 5,058 x 3
date flow year
<date> <dbl> <dbl>
1 1983-10-01 3.31 1984
2 1983-10-02 3.19 1984
3 1983-10-03 3.7 1984
4 1983-10-04 3.83 1984
5 1983-10-05 3.44 1984
6 1983-10-06 4.37 1984
7 1983-10-07 6.78 1984
8 1983-10-08 6.3 1984
9 1983-10-09 6.46 1984
10 1983-10-10 6.62 1984
# … with 5,048 more rows

How plot timing graph with specific options

I have this data.table which has 3 columns. the first one is about MonthlySalesMean , the second is the year and then the month.
> data[,MonthlySalesMean:=mean(StoreMean),by=c("DateMonth","DateYear")][,c("MonthlySalesMean","DateYear","DateMonth")]
MonthlySalesMean DateYear DateMonth
1: 6839.340 2015 7
2: 6839.340 2015 7
3: 6839.340 2015 7
4: 6839.340 2015 7
5: 6839.340 2015 7
---
641938: 6852.171 2013 1
641939: 6852.171 2013 1
641940: 6852.171 2013 1
641941: 6852.171 2013 1
641942: 6852.171 2013 1
I need to plot a graph of three lines because I have 3 years:
> unique(data[,DateYear])
[1] 2015 2014 2013
>
And For each year or each line, it should be plotted across all months of a year the MonthlySalesMean values. In another word it should be like this graph:
How can I do this, please?
thank you for advance!
Without a reproducible example, I can't test with your data, but here's the idea. You plot a path, with aesthetics of sales (y) against month (x) grouped by year (color)
library(tidyverse)
example_data <- tibble(
MonthlySalesMean = rnorm(36, 100, 20),
DateYear = c(rep(2013, 12), rep(2014, 12), rep(2015, 12)),
DateMonth = c(1:12, 1:12, 1:12)
)
ggplot(example_data, aes(x = DateMonth, y = MonthlySalesMean, color = as.factor(DateYear))) +
geom_path() +
geom_point(size = 2) +
geom_text(aes(label = DateYear),
data = filter(example_data, DateMonth == 1),
nudge_x = -0.5) + # plot year numbers
scale_x_continuous(breaks = 1:12, labels = month.abb) +
scale_colour_manual(guide = FALSE, # hides legend
values = c("red", "green", "blue")) + # custom colors
expand_limits(x = 0.5) + # adds a space before January
labs(x = "Month", y = "Sales") +
theme_bw() +
theme(panel.grid = element_blank()) # removes gridlines

Add several lines of variable text in fixed positions to a ggplot facet

I am tryig to add several lines of text to this facet. Sorry about the mess of code
From the object means1 I want to add the values of the variables "pCensCom" "pCensEx" and "pCensReg" for each facet, as described in the following figure
This is the object 'censTot1' used to build the chart
censo censTot tipoAni censAn año pCensAn
1: 2010-01-01 42 Hembra adulta 27 2010 64.285714
2: 2010-01-01 42 Joven 4 2010 9.523810
3: 2010-01-01 42 Macho adulto 1 2010 2.380952
4: 2010-01-01 42 Ternero 10 2010 23.809524
5: 2010-01-02 42 Hembra adulta 27 2010 64.285714
---
7300: 2014-12-30 57 Ternero 16 2014 28.070175
7301: 2014-12-31 57 Hembra adulta 32 2014 56.140351
7302: 2014-12-31 57 Joven 7 2014 12.280702
7303: 2014-12-31 57 Macho adulto 2 2014 3.508772
7304: 2014-12-31 57 Ternero 16 2014 28.070175
The following describes the code used to design the figure
# Plot color background
# %%%%%%%%%%%%%%%%%%%%%%
bg0<-data.table()
for(i in 1:5){
bg<-data.table(xstart=c(as.Date(paste0(años[i],"-01-01"), format="%Y-%m-%d"),as.Date(paste0(años[i],"-03-21"), format="%Y-%m-%d"), as.Date(paste0(años[i],"-06-21"),format = "%Y-%m-%d"),as.Date(paste0(años[i],"-09-21"),format = "%Y-%m-%d"),
as.Date(paste0(años[i],"-12-21"),format = "%Y-%m-%d")),xend=c(as.Date(paste0(años[i],"-03-21"), format="%Y-%m-%d"),
as.Date(paste0(años[i],"-06-21"),format = "%Y-%m-%d"), as.Date(paste0(años[i],"-09-21"),format = "%Y-%m-%d"),
as.Date(paste0(años[i],"-12-21"),format = "%Y-%m-%d"),as.Date(paste0(años[i],"-12-31"),format = "%Y-%m-%d")),
Estacion=c("Invierno","Primavera","Verano","Otoño","Invierno"))
l=list(bg0,bg); bg0<-rbindlist(l, fill=TRUE)
}
bg0<-bg0[,Estacion:=factor(ordered(Estacion,levels=c("Invierno","Primavera", "Verano", "Otoño")))]
cbPalette<-c("#FF3300","#006633","#FFFF00","#0000FF")
plotbg<-ggplot()+ geom_rect(data = bg0, aes(xmin = xstart, xmax = xend, ymin = 0, ymax = Inf, fill = Estacion), alpha = 0.10)+ scale_fill_manual(values=cbPalette)+ guides(fill=FALSE)+theme_bw()
means1<-data.table(tipoAni=c("Hembra adulta","Joven","Macho adulto","Ternero"),pCensCom=c(62.3,17.8,0.9,19.37),pCensEx=c(61.4,16.1,1.9,20.6),pCensReg=c(63.0,17.9,1.6,24.7))
# Plot
# %%%%
plotbg + geom_line(data=censTot1,aes(x=censo,y=pCensAn))+ facet_grid(tipoAni ~ .)+ xlab("Censos diarios") + ylab("Animales (%)") +theme_bw()+ theme(strip.text.x = element_text(size=8),strip.text.y = element_text(size=10, face="bold"),strip.background = element_rect(colour="red", fill="#CCCCFF"))
Please I need help, I tried several times using the functions annotation_custom, grobTree and textGrob and I have not been able to achieve
Here is a simplified answer. First I simulate some data dat, then a second data.table backgr that has the information for the background, and lastly textdt, which holds the information about the text elements.
The code looks like this:
library(data.table)
library(ggplot2)
library(scales)
dat <- data.table(x = rep(1:100, 2),
group = rep(LETTERS[1:2], each = 100),
val = rnorm(200))
dat[, price := 100 + cumsum(val), by = group]
# plot empty
ggplot(dat, aes(x = x, y = price)) +
geom_line() +
facet_grid(group~.)
# plot with added polygons
# for the background colors
backgr <- data.table(minval = c(10, 40, 60, 90),
maxval = c(20, 60, 80, 100),
backgroup = LETTERS[1:4])
# for the text elements
textdt <- data.table(xval = c(10, 50, 70),
yval = c(105, 100, 95),
textlabel = c("foo", "bar", "lorum"),
group = c("A", "A", "B"))
# plot
ggplot() +
geom_rect(data = backgr, aes(xmin = minval, xmax = maxval, ymin = -Inf,
ymax = Inf, fill = backgroup)) +
geom_line(data = dat, aes(x = x, y = price)) +
geom_text(data = textdt, aes(x = xval, y = yval, label = textlabel,
group = group)) +
facet_grid(group~.) +
scale_fill_manual(values = alpha(c("red", "green", "blue", "yellow"), 0.5))
Which results in a plot like this, which you can adjust to fit your data:

Resources