Reordering month results in the x axis (ggplot) - r

I'd like to produce a plot with reordered months on the x axis (instead of starting in Jan and ending in Dec, I'd like to start on Apr and end on Mar).
My data is something like:
Month An Fiscal.Year Month.Number Month.Name
1 2009-04-01 40488474 2009 4 Apr
2 2009-05-01 53071971 2009 5 May
3 2009-06-01 24063572 2009 6 Jun
...
44 2012-11-01 39457771 2012 11 Nov
45 2012-12-01 44045572 2012 12 Dec
46 2013-01-01 90734077 2012 1 Jan
My code for producing the plot is:
g <- ggplot(data = data, aes(x = Month.Number, y = An)) +
geom_line(aes(group = Fiscal.Year, colour = factor(Fiscal.Year))) +
scale_x_discrete(
name = "Month",
breaks = data$Month.Number,
labels = data$Month.Name
) +
scale_y_continuous();
but the result is a plot ordered by month from Jan to Dec, not from Apr to Mar as I want.
I've tried the limits option inside scale_x_discrete, but I think this just reorders the x axis labels, not the real data.
Could you please help me?
Thanks in advance for your answer!

You have to reorder the factor levels of Month.Name. Assuming dfis your data.frame:
df$Month.Name <- factor( df$Month.Name, levels = c( "Apr", "May", ..., "Feb", "Mar" ) )
g <- ggplot(data = df, aes(x = Month.Name, y = An) ) +
geom_line(aes(group = Fiscal.Year, colour = factor(Fiscal.Year))) +
scale_x_discrete( name = "Month" ) +
scale_y_continuous();
Alternatively you can just change Month.Number such that, Apr is 1, May is 2 and so on...

Just run before plotting:
data$Month.Number <- ((data$Month.Number+8) %% 12) + 1

Related

geom_rect: background color repeated per season

I have a dataframe like this:
df<-data.frame(Category= c("a","b","a","b"), Value = c(25,90,40,10), Date= c("2016-02-13", "2016-05-13", "2016-08-13", "2016-11-13"))
In reality it is more complex, has several years and several observed objects so that it should be a faceted plot in the end, but I think this has nothing to do with the question.
I want to have a ggplot (line plot), where every season got it's own background color.
e.g.: spring from March to May in yellow,
summer from June to August in red
autumn from September to November in blue
and winter from December to February in grey.
This should be repeated, regardless the year as it goes through several years and the database will be updated with time.
I tried a lot with geom_rect but didn't find a working solution.
Thanks for any advice!
If I understand your goal correctly, I think you can achieve it by creating two additional variables, say Season and Color that correspond to Date column, and then supply the columns as necessary to geom_line.
To make the steps and the results clearer, I create a dummy data by expanding your data to another year (2017) with similar date and category but slightly different values:
1. The data
df<-data.frame(Category= c("a","b","a","b"), Value = c(25,90,40,10), Date= c("2016-02-13", "2016-05-13", "2016-08-13", "2016-11-13"))
df2<-data.frame(Category= c("a","b","a","b"), Value = c(30,95,45,15), Date= c("2017-02-13", "2017-05-13", "2017-08-13", "2017-11-13"))
dat <- rbind.data.frame(df,df2)
dat
Category Value Date
1 a 25 2016-02-13
2 b 90 2016-05-13
3 a 40 2016-08-13
4 b 10 2016-11-13
5 a 30 2017-02-13
6 b 95 2017-05-13
7 a 45 2017-08-13
8 b 15 2017-11-13
2. Creating Season and Color columns
dat.season <- dat %>%
mutate(Date = as.Date(Date)) %>%
mutate(Month = months(Date)) %>%
mutate(Season = case_when(Month %in% c("March", "April", "May") ~ "spring",
Month %in% c("June", "July", "August") ~ "summer",
Month %in% c("September", "October", "November") ~ "autumn",
Month %in% c("December", "January", "February")~ "winter")) %>%
mutate(Color = case_when(Season == "spring"~ "yellow",
Season == "summer"~ "red",
Season == "autumn"~ "blue",
Season == "winter"~ "grey"))
dat.season
Category Value Date Month Season Color
1 a 25 2016-02-13 February winter grey
2 b 90 2016-05-13 May spring yellow
3 a 40 2016-08-13 August summer red
4 b 10 2016-11-13 November autumn blue
5 a 30 2017-02-13 February winter grey
6 b 95 2017-05-13 May spring yellow
7 a 45 2017-08-13 August summer red
8 b 15 2017-11-13 November autumn blue
Supplying the columns to geom_line()
dat.season %>% ggplot() +
geom_line(aes(x = Date, y = Value),
colour = dat.season$Color) +
theme_bw()
The result
Update to add coloured background
Here is the line plot along with coloured backgrounds for each season.
dat.season %>%
ggplot() +
geom_rect(aes(xmin = Date[1], xmax = Date[2],
ymin = Value[1], ymax = Value[2]),
fill = dat.season$Color[1])+
geom_rect(aes(xmin = Date[2], xmax = Date[3],
ymin = Value[2], ymax = Value[3]),
fill = dat.season$Color[2])+
geom_rect(aes(xmin = Date[3], xmax = Date[4],
ymin = Value[3], ymax = Value[4]),
fill = dat.season$Color[3])+
geom_rect(aes(xmin = Date[4], xmax = Date[5],
ymin = Value[4], ymax = Value[5]),
fill = dat.season$Color[4])+
geom_rect(aes(xmin = Date[5], xmax = Date[6],
ymin = Value[5], ymax = Value[6]),
fill = dat.season$Color[5])+
geom_rect(aes(xmin = Date[6], xmax = Date[7],
ymin = Value[6], ymax = Value[7]),
fill = dat.season$Color[6])+
geom_rect(aes(xmin = Date[7], xmax = Date[8],
ymin = Value[7], ymax = Value[8]),
fill = dat.season$Color[7])+
geom_line(aes(x = Date, y = Value)) +
theme_bw()
The result

seasonal plot Error in data.frame(y = as.numeric(x)) arguments imply differing number of rows:

here is my Code:
month year GrandTotal Date
1 6 2014 15172331 2014-06-30
2 7 2014 24381383 2014-07-31
3 8 2014 24351338 2014-08-31
...
46 3 2018 85980914 2018-03-31
47 4 2018 72723488 2018-04-30
y <- ts(briskaranged, start=2014, frequency=12)
library(ggplot2)
#ploting of variables
autoplot(y) +
labs(x ="Date", y = "GrandTotal", title = "Amount, ggplot2")
#seasonalplot
ggseasonplot(y, year.labels=TRUE, year.labels.left=TRUE) +
ylab("amount") +
ggtitle("Seasonal plot: amount transaction per day")
but compiler show error
Error in data.frame(y = as.numeric(x), year = trunc(time(x)), cycle =
as.numeric(cycle(x)), :
arguments imply differing number of rows: 235, 47
y <- ts(briskaranged$GrandTotal, start=2014, frequency=12)
library(ggplot2)
#ploting of variables
autoplot(y) +
labs(x ="Date", y = "GrandTotal", title = "Amount, ggplot2")
#seasonalplot
ggseasonplot(y, year.labels=TRUE, year.labels.left=TRUE) +
ylab("amount") +
ggtitle("Seasonal plot: amount transaction per day")

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

Different line types in one ggplot graph

I want to create a line graph in ggplot2 that contains different line types.
I tried it like this:
library(ggplot2)
library(tidyr)
head(a)
a <- read.table(text = "m A B C
1 Okt 9.250 14.75475 5.94375
2 Nov 10.343 16.21625 7.88050
3 Dez 14.885 25.81775 10.13550
4 Jan 15.566 25.17125 11.70950
5 Feb 15.619 22.53175 11.80400", header = TRUE)
a$m <- factor(a$m, levels = c("Okt", "Nov", "Dez", "Jan", "Feb"))
xy <- gather(a, key = variable, value = value, -m)
ggplot(xy, aes(x = m, y = value, color = variable)) +
geom_line(aes(linetype=variable))
But the plot doesn't show any lines at all. I would like the A line to be a solid line and B and C dashed lines.
You need to set group = variable in your aes:
ggplot(xy, aes(x = m, y = value, color = variable, group = variable)) +
geom_line(aes(linetype=variable))
This is necessary because your m x-axis is a factor, not a continuous variable, meaning geom_line doesn't know to connect them.

scaling x-axis in ggplot

I have an Object classt of xts. I would like to plot this object with ggplot2
my xtsobject:
structure(c(463829L, 469849L, 608148L, 470825L, 560057L, 431183L,
418000L, 508168L, 422579L, 589829L, 462264L, 487183L, 612174L,
467904L, 454620L, 450243L, 549898L, 422026L, 508311L, 385633L,
420200L, 619074L, 462605L, 465353L, 565804L, 464841L, 505977L,
624608L, 491175L, 459701L, 563406L, 461595L, 499607L, 674799L,
505167L, 637375L, 500131L, 473494L, 488527L, 613972L, 468938L,
454034L, 566511L, 456879L, 592797L, 491368L, 481690L, 597927L
), .Tsp = c(2012, 2015.91666666667, 12), class = "ts")
I woulf like to have also month numbers on my plot. I have tried this code:
library(ggplot2)
library(zoo)
library(scales)
autoplot(as.zoo(a2)) + geom_line()
+scale_x_date(format = "%b-%Y")
but I get this error:
Error in continuous_scale(aesthetics, "date", identity, breaks = breaks, :
unused argument (format = "%b-%Y")
What should I do to do this job? Like this plot but with month:
Simply try this:
a2 <- read.table(text=' Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
2012 463829 469849 608148 470825 560057 431183 418000 508168 422579 589829 462264 487183
2013 612174 467904 454620 450243 549898 422026 508311 385633 420200 619074 462605 465353
2014 565804 464841 505977 624608 491175 459701 563406 461595 499607 674799 505167 637375
2015 500131 473494 488527 613972 468938 454034 566511 456879 592797 491368 481690 597927', header=TRUE)
library(ggplot2)
library(reshape2)
a2$year <- rownames(a2)
a2 <- melt(a2)
ggplot(a2, aes(variable, value, group=year)) + geom_line() + facet_wrap(~year, ncol=1)
with output
or all in one plot:
ggplot(a2, aes(variable, value, group=year, col=year)) + geom_line()
with output
or this:
a2 <- read.table(text=' Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
2012 463829 469849 608148 470825 560057 431183 418000 508168 422579 589829 462264 487183
2013 612174 467904 454620 450243 549898 422026 508311 385633 420200 619074 462605 465353
2014 565804 464841 505977 624608 491175 459701 563406 461595 499607 674799 505167 637375
2015 500131 473494 488527 613972 468938 454034 566511 456879 592797 491368 481690 597927', header=TRUE)
a2$year <- rownames(a2)
a2 <- melt(a2, id='year')
a2$date <- as.Date(paste(a2$year, a2$variable, '01'), '%Y %b %d')
ggplot(a2, aes(date, value)) + geom_line() +
scale_x_date(date_breaks = "months", date_labels = "%b %Y") +
theme(axis.text.x = element_text(angle = 90))
with output
I think the problem is that the index to your time series is in decimal date (i.e., numeric) format, and scale_x_date is expecting something in date format.
Here's some code that gets close to what I think you want. It involves creating a zoo object with the index in date format first, then plotting that. Like:
a3 <- zoo(a2, order.by = as.Date(yearmon(index(a2))))
p <- autoplot(a3)
p + scale_x_date(date_breaks = "1 month")
+ theme(axis.text.x = element_text(angle = 90))
I think you'll want to tinker with the options in scale_x_date to improve the look of the result, but this should get you on the right path, I think.
test this option in the ggplot.
+scale_x_date(labels=date_format("%Y-%m")
Note that the class of a2 is not "xts" -- it is a "ts" class object. Anyways, first convert the index to class "yearmon" and then use scale_x_yearmon like this:
z <- as.zoo(a2)
index(z) <- as.yearmon(index(z))
autoplot(z) + scale_x_yearmon()

Resources