I've got a plot that is tabulating two types of data by day and I'm looking to just trim the first and last label from the plot. Here is a reproducible example of the data:
library(dplyr)
library(ggplot2)
library(scales)
dates <- paste0("2014-01-", 1:31)
dat <- data.frame("Date" = sample(dates, 4918, replace=T),
"Type" = sample(c('Type1', 'Type2'), 4918, replace=T, probs=c(.55, .45)))
p.data <- dat %>% group_by(Date, Type) %>% summarise(Freq = n())
p.data$Date <- as.Date(p.data$Date)
Here is the code for the plot:
p <- ggplot(data=p.data, aes(x=Date, y=Freq, fill=Type)) +
geom_bar(stat='identity', position='dodge') +
labs(x='Date', y='Count', title='Frequency of Data by Day') +
theme_bw() +
theme(axis.text.x = element_text(angle=90),
panel.grid.minor = element_blank(),
plot.title = element_text(vjust=1.4),
legend.position='bottom') +
scale_x_date(labels=date_format("%a %d"),
breaks=date_breaks("day"),
limits=c(as.Date('2014-01-01'), as.Date('2014-01-31'))) +
scale_y_continuous(limits=c(0, 150), breaks=seq(from=0, to=150, by=25)) +
scale_fill_manual(values=c('dark grey', 'light green'))
As you can see, there are two label points for the day prior to the beginning of the month and the day after the last day of the month. How do I trim those off? Can I just subset the labels and breaks call in scale_x_date()?
The expand argument in scale_x_date is one way to do it. It tries to be helpful by making some extra space around the edges, but in this case it adds more than a day, so the axis labels have those extra days.
p <- ggplot(data=p.data, aes(x=Date, y=Freq, fill=Type)) +
geom_bar(stat='identity', position='dodge') +
labs(x='Date', y='Count', title='Frequency of Data by Day') +
theme_bw() +
theme(axis.text.x = element_text(angle=90),
panel.grid.minor = element_blank(),
plot.title = element_text(vjust=1.4),
legend.position='bottom') +
scale_x_date(labels=date_format("%a %d"),
breaks=date_breaks("day"),
limits=c(as.Date('2014-01-01'), as.Date('2014-01-31')),
expand=c(0, .9)) +
scale_y_continuous(limits=c(0, 150), breaks=seq(from=0, to=150, by=25)) +
scale_fill_manual(values=c('dark grey', 'light green'))
Related
My x axis is showing number instead of months, how can I modify so it shows January, February and March?
data<- data.frame(Dates= rep(
seq(as.Date('2017-01-01'), as.Date('2017-03-03'), by = 'months')),
A=c(28.0,20.6,15.8),
B= c(0,12.7,6.5),
C= c(0,1.49,6.96),
Variable1= c(1,1,1))
trans_x <- function(x)round(coef(m1)[1] + coef(m1)[2]*x)
ggplot() +
geom_scatterpie(data = data, aes(x = Dates , y = Variable1, group = Dates, r=4), cols = c("A","B","C")) +
scale_y_log10() +
coord_fixed()+
theme_classic()+
theme(axis.text.y = element_blank())+
scale_fill_grey()
As #Mohanasundaram said right in the comments, you can use the scales package to format your date using date_format in the scale_x_date function like this:
library(tidyverse)
library(scatterpie)
library(scales)
ggplot() +
geom_scatterpie(data = data, aes(x = Dates , y = Variable1, group = Dates, r=4), cols = c("A","B","C")) +
scale_y_log10() +
coord_fixed()+
theme_classic()+
theme(axis.text.y = element_blank())+
scale_fill_grey() +
scale_x_date(labels = date_format("%Y-%B-%d"))
Output:
I have three plots and I want to show them in a figure like below
link
I made a few attempts but I was not successful. My codes are given below:
dat <- read.table(text="
dates PS.230 PS.286 PS.389
3.01.2018 20.75103 16.69312 -6.503637
15.01.2018 15.00284 16.03211 16.1058
8.02.2018 11.0789 7.438522 -2.970704
20.02.2018 15.10865 12.8969 3.935687
4.03.2018 24.74799 19.25148 9.186779
28.03.2018 -1.299456 7.028817 -8.126284
9.04.2018 4.778902 8.309322 -3.450085
21.04.2018 7.131915 9.484932 -4.326919
", header=T, stringsAsFactors=FALSE)
dat$dates <- as.Date(dat$dates, "%d.%m.%Y")
library(ggplot2)
library(tidyverse)
a <- ggplot(dat, aes(x=dates, y=PS.230)) +
geom_point() +
geom_line() +
geom_smooth(se = FALSE, method = lm, size = 0.15, color = "#da0018") + #cizgi eklemek icin
scale_x_date(date_breaks = "1 months",date_labels = "%Y-%m",
limits = as.Date.character(c("01/12/2017","31/12/2018"),
format = "%d/%m/%Y")) +
ylim(-20,40) +
ylab("[mm/year]") +
xlab("") +
theme_linedraw() #theme_light
a + theme(
axis.text.x = element_text(angle = 45, hjust = 1),
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank()
)
b <- ggplot(dat, aes(x=dates, y=PS.286)) +
geom_point() +
geom_line() +
geom_smooth(se = FALSE, method = lm, size = 0.15, color = "#da0018") + #cizgi eklemek icin
scale_x_date(date_breaks = "1 months",date_labels = "%Y-%m",
limits = as.Date.character(c("01/12/2017","31/12/2018"),
format = "%d/%m/%Y")) +
ylim(-20,40) +
ylab("[mm/year]") +
xlab("") +
theme_linedraw() #theme_light
b + theme(
axis.text.x = element_text(angle = 45, hjust = 1),
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank()
)
c <- ggplot(dat, aes(x=dates, y=PS.389)) +
geom_point() +
geom_line() +
geom_smooth(se = FALSE, method = lm, size = 0.15, color = "#da0018") + #cizgi eklemek icin
scale_x_date(date_breaks = "1 months",date_labels = "%Y-%m",
limits = as.Date.character(c("01/12/2017","31/12/2018"),
format = "%d/%m/%Y")) +
ylim(-20,40) +
ylab("[mm/year]") +
xlab("") +
theme_linedraw() #theme_light
c + theme(
axis.text.x = element_text(angle = 45, hjust = 1),
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank()
)
in the link I provided, much better graphics were drawn with fewer lines. my codes seem a little more complicated and frankly i couldn't get out. a, b and c plots in one image and only one date axes. How can I modify the codes to achieve sample result? Thank you.
Thank you for posting your data. As mentioned, the first step is to arrange your dataset so that it is in Tidy Data format. The information in dat$PS.230, dat$PS.286 and dat$PS.389 should be better represented in two columns:
First Column: name of data type - We'll call this column dat$value_type and it will have values that indicate if dat$results comes from PS.230, PS.286, or PS.389.
Second Column: value of data - We'll call this column dat$result and it just shows the value. This will be the y= aesthetic for all plots.
Pre-Processing: Gather into TidyData format
Use the gather() function to gather all columns in to a key ("value_type") and a "value" ("result"). We'll gather all columns except for "dates", so we just note to exclude that column via -dates:
dat <- dat %>% gather(key='value_type', value='result', -dates)
Plot
For the plot, you apply x and y aesthetics to "date" and "result". You can use "value_type" to differentiate based on color and create your legend for points and lines. You also use "value_type" as the column for creating the facets (the three separate plots) via use of facet_grid() function. Note that value_type ~ . arranges by "value_type" vertically, whereas . ~ value_type would arrange horizontally:
ggplot(dat, aes(x=dates, y=result)) +
geom_line(aes(color=value_type)) +
geom_point(aes(color=value_type)) +
scale_x_date(date_breaks = '1 months', date_labels = '%Y-%m') +
facet_grid(value_type ~ .) +
theme_bw()
I am a new user in R and I hope you can help me.
setwd("C:/Users/USER/Desktop/Jorge")
agua <- read_excel("agua.xlsx")
pbi <- read_excel("PBIagro.xlsx")
str(agua);
names(agua)[2] <- "Variación";
agua[,1] <- as.Date(agua$Trimestre)
lagpbi <- lag(pbi$PBIAgropecuario, k=1)
pbi[,3]<- lagpbi; pbi <- pbi[-c(1),];
names(pbi)[3] <- "PBIlag"
growth <- ((pbi$PBIAgropecuario-pbi$PBIlag)/pbi$PBIlag)*100
Anual_growth <- data.frame(growth); Anual_growth[,2] <- pbi$Año; names(Anual_growth)[2] <- "Año"
# Plot
Agro <- ggplot(Anual_growth, aes(x=Año, y=growth)) +
geom_line(color="steelblue") +
geom_point() +
geom_text(aes(label = round(Anual_growth$growth, 1)),
vjust = "inward", hjust = "inward", size=2.5, show.legend = FALSE) +
xlab("") +
theme_ipsum() +
theme(axis.text.x=element_text(angle=60, hjust=1)) +
ylim(-9.9,13.4) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
axis.line.x = element_blank(), plot.margin = unit(c(1,1,0.5,1),"cm"),
axis.line.y = element_blank(), axis.text.x=element_text(face = "bold", size=8,
angle=1,hjust=0.95,vjust=0.2),
axis.text.y = element_blank(), axis.title.y=element_blank())+
scale_x_continuous("Año", labels = as.character(Anual_growth$Año), breaks = Anual_growth$Año)
print(Agro)
The problem is that it shows all the years, but I only want pair years (in X-axis) or years with step equal to 2.
I hope you can really help me.
Thank you.
Notice that the X-axis variable is a numeric string.
You can add something like
scale_x_date(date_breaks = "2 years", date_labels = "%Y") to your ggplot.
This is how it looks with my data, since you haven't posted yours. I am plotting a type date on x axis.
1.
ggplot(mydata) +
aes(x = date, y = number, color = somevar) +
geom_line()
ggplot(mydata) +
aes(x = date, y = number, color = somevar) +
geom_line() +
scale_x_date(date_breaks = "1 year", date_labels = "%Y")
3.
ggplot(mydata) +
aes(x = date, y = number, color = somevar) +
geom_line() +
scale_x_date(date_breaks = "2 years", date_labels = "%Y")
If you want pair years and because your x-axis variable is numeric, you can specify in scale_x_continous that breaks argument should take only even numbers.
Here how you can do it using this small example:
year = 1998:2020
value = rnorm(23,mean = 3)
df = data.frame(year,value)
library(ggplot2)
ggplot(df, aes(x = year, y = value))+
geom_point()+
geom_line()+
scale_x_continuous(breaks = year[year %%2 ==0])
Reciprocally, if you want odd years, you just have to specify scale_x_continuous(breaks = year[year %%2 != 0])
So, in your code, you should write:
scale_x_continuous(breaks = Anual_growth$Año[Anual_growth$Año %%2 ==0])
Does it answer your question ?
I would appreciate your help in the following: I'm trying to build a stacked barplot. The fill is the split of business (new and renewed), the Y axis is volume of new/renewed business and the X would be the month. In my data I have two years of history, so I would like to have two stacked columns per month, one for n-1 year and one for n year. However, I don't know how to do this last step...
To clarify, please find below a picture of the data, the plot I have so far and a drawing of my goal.
And here is the code:
ggplot(BUSINESS, aes(fill=Business, y=GWP_mio, x=Date)) +
geom_bar(position="stack", stat="identity") +
scale_fill_manual(values = c("#009E73","Darkblue")) +
scale_y_continuous(breaks=seq(0,18000000,1000000), labels = scales::comma_format(scale = 1/1000000,
accuracy = .1), limits = c(0,18000000)) +
theme_ipsum() +
ggtitle('GWP development') +
theme(plot.title = element_text(hjust=0.5, size=14, family="Calibri", face="bold"),
legend.title = element_text(size=11, family="Calibri", face="bold"),
axis.title.x = element_text(hjust=1, size=11, family="Calibri", face="bold"),
axis.text.x = element_text(angle=90, hjust=1, size=11, family="Calibri"),
axis.title.y = element_text(angle=0, hjust=1, size=10, family="Calibri", face="bold"))
Any help would be highly appreciated.
[2
[]3
What you're asking for is both position= 'dodge' and position= 'stack'. I'd actually suggest using faceting:
Data
library(data.table)
library(ggplot2)
N <- 24
dat <- data.table(
date= rep(seq.Date(as.Date('2017-01-01'), as.Date('2018-12-01'), '1 month'), each= 2)
, new= rpois(n= 2 * N, lambda= 5)
, renew= rpois(n= 2 * N, lambda= 4)
)
dat[,year := data.table::year(date)]
dat[,month:= data.table::month(date)]
dat <- melt(dat, id.vars= c("date", "year", "month"), variable.name= 'business_type', value.name= 'units')
Facet
This is going to be much easier for the viewer.
ggplot(dat, aes(x= month, y= units, fill= factor(year))) +
geom_bar(position= 'dodge', stat='identity') + facet_grid(business_type ~ .) +
theme(axis.text.x= element_text(angle= 90))
Solution
But that's not what you asked for. So let's do something hacky. You'll have to mess around with the colours / fill to get exactly what you want. But here we add a first layer for the total, then a second layer for the new
N <- 24
dat <- data.table(
date= rep(seq.Date(as.Date('2017-01-01'), as.Date('2018-12-01'), '1 month'), each= 2)
, new= rpois(n= 2 * N, lambda= 5)
, renew= rpois(n= 2 * N, lambda= 4)
)
dat[,year := data.table::year(date)]
dat[,month:= data.table::month(date)]
dat[, total := new + renew]
ggplot(dat, aes(x= month, y= total, fill= factor(year))) +
geom_bar(stat= 'identity', position= 'dodge', ) +
geom_bar(data= dat, aes(x= month, y= new, fill= "black", colour= factor(year)), stat= 'identity', position= 'dodge') +
scale_color_brewer(palette = "Dark2")
I have a set of data with date and time. I want to plot time on the y-axis and date on the x-axis, and plot the number of observations at a given time during each day. However, my observations start at around 20.00 on the first day, and end around 06.00 the next day. So, when I plot this, R plots all observations on each date:
Here is a link to a picture of my current graph:
Does anyone know how to define the y-axis to start at one date and end at the next date?
Here is my script:
library(ggplot2)
library(scales)
library(dplyr)
library(lubridate)
test$DATE <- as.Date(test$DATE, format = "%d.%m.%Y", tz = "UTC")
test$hms <- format(test$TIME, format = "%H:%M:%S")
test$hms <- as.POSIXct(test$hms, format = "%H:%M:%S")
ggplot(test, aes(test$DATE,test$hms)) +
geom_point() +
geom_smooth() +
theme_light() + theme(legend.position="top") +
scale_color_brewer(palette = 1, type = "qual") +
ggtitle("emergence/return time") +
scale_x_date("d",date_breaks="7 days",date_labels="%d-%m")+
scale_y_datetime("Time",breaks=date_breaks("60 min"),labels =
date_format("%H:%M"))
g <- ggplot(test, aes(test$DATE,test$hms)) +
geom_point() +
geom_smooth() +
theme_light() + theme(legend.position="top") +
scale_color_brewer(palette = 1, type = "qual") +
ggtitle("emergence/return time") +
scale_x_date("d",date_breaks="7 days",date_labels="%d-%m")+
scale_y_datetime("Time",breaks=date_breaks("60 min"),labels =
date_format("%H:%M"))
g + scale_colour_grey()+theme(
panel.grid.major.y = element_blank(),
panel.grid.minor.y = element_blank(),panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank())