I am a beginner in ggplot2. I am unable to use date_minor_breaks to show quarterly "ticks" on x-axis.
Here's my code:
x<-c(seq(1:12))
time<-c("2010Q1","2010Q2","2010Q3","2010Q4","2011Q1","2011Q2", "2011Q3","2011Q4","2012Q1","2012Q2","2012Q3","2012Q4")
z<-data.frame(type = x,time = time)
z$time = as.yearqtr(z$time)
z$time = as.Date(z$time)
ggplot(data = z, aes(x=time,y=type)) +
geom_point() +
scale_x_date(date_labels = "%Y",date_minor_breaks = "3 months",name = "Year") +
theme_tufte() +
theme(legend.position = "none")
I researched this topic on SO Formatting dates with scale_x_date in ggplot2 and on https://github.com/hadley/ggplot2/issues/542, and found that there were some issues reported on this topic. However, I didn't quite follow the conversation about changes to ggplot2 because it's been only 6 days since I started using ggplot2.
Here's the graph I got (it doesn't have any ticks)...
Here's a sample graph with "tick marks" generated from Excel. Please ignore values because my point of creating this Excel chart is to demonstrate what I am looking for--i.e. "quarterly ticks". I'd appreciate your help.
You may have to make major breaks every three months and then pad your labels with blanks to give the illusion of major (labeled) and minor (unlabeled) ticks. See this answer for another example.
First manually make the breaks for the tick marks at every quarter.
breaks_qtr = seq(from = min(z$time), to = max(z$time), by = "3 months")
Then make the year labels and pad these labels with three blanks after each number.
labels_year = format(seq(from = min(z$time), to = max(z$time), by = "1 year"), "%Y")
labs = c(sapply(labels_year, function(x) {
c(x, rep("", 3))
}))
Now use the breaks and the labels with the labels and breaks arguments in scale_x_date. Notice that I'm not using date_labels and date_breaks for this.
ggplot(data = z, aes(x=time,y=type)) +
geom_point() +
scale_x_date(labels = labs, breaks = breaks_qtr, name = "Year") +
theme_tufte() +
theme(legend.position = "none")
You should also define your (major) date breaks:
ggplot(data = z, aes(x=time, y=type)) +
geom_point() +
scale_x_date(date_breaks = "1 year", name = "Year", date_minor_breaks="3 months",
limits = c(as.Date(as.yearqtr("2009Q4")),
as.Date(as.yearqtr("2013Q2"))),
expand=c(0,0), date_labels = "%Y") +
theme(legend.position = "none")
And some other "fancy" stuff to align the minor ticks with the major ticks (I guess there a better ways to do this, but this works).
Related
I'm having a very, very tough time getting the x-axis to look correct for my graphs.
Here is my data (generated via dput()):
df <- structure(list(Month = structure(1:12, .Label = c("2011-07-31", "2011-08-31", "2011-09-30", "2011-10-31", "2011-11-30", "2011-12-31", "2012-01-31", "2012-02-29", "2012-03-31", "2012-04-30", "2012-05-31", "2012-06-30"), class = "factor"), AvgVisits = c(6.98655104580674,7.66045407330464, 7.69761337479304, 7.54387561322994, 7.24483848458728, 6.32001400498928, 6.66794871794872, 7.207780853854, 7.60281201431308, 6.70113837397123, 6.57634103019538, 6.75321935568936)), .Names = c("Month","AvgVisits"), row.names = c(NA, -12L), class = "data.frame")
Here is the chart I am trying to graph:
ggplot(df, aes(x = Month, y = AvgVisits)) +
geom_bar() +
theme_bw() +
labs(x = "Month", y = "Average Visits per User")
That chart works fine - but, if I want to adjust the formatting of the date, I believe I should add this:
scale_x_date(labels = date_format("%m-%Y"))
I'm trying to make it so the date labels are 'MMM-YYYY'
ggplot(df, aes(x = Month, y = AvgVisits)) +
geom_bar() +
theme_bw() +
labs(x = "Month", y = "Average Visits per User") +
scale_x_date(labels = date_format("%m-%Y"))
When I plot that, I continue to get this error:
stat_bin: binwidth defaulted to range/30. Use 'binwidth = x' to adjust this.
Despite hours of research on formatting of geom_line and geom_bar, I can't fix it. Can anyone explain what I'm doing wrong?
Edit: As a follow-up thought: Can you use date as a factor, or should you use as.Date on a date column?
To show months as Jan 2017 Feb 2017 etc:
scale_x_date(date_breaks = "1 month", date_labels = "%b %Y")
Angle the dates if they take up too much space:
theme(axis.text.x=element_text(angle=60, hjust=1))
Can you use date as a factor?
Yes, but you probably shouldn't.
...or should you use as.Date on a date column?
Yes.
Which leads us to this:
library(scales)
df$Month <- as.Date(df$Month)
ggplot(df, aes(x = Month, y = AvgVisits)) +
geom_bar(stat = "identity") +
theme_bw() +
labs(x = "Month", y = "Average Visits per User") +
scale_x_date(labels = date_format("%m-%Y"))
in which I've added stat = "identity" to your geom_bar call.
In addition, the message about the binwidth wasn't an error. An error will actually say "Error" in it, and similarly a warning will always say "Warning" in it. Otherwise it's just a message.
When I plot using ggplot I get grey vertical lines on my plot before data chart. Any ideas on how to remove it would be highly appreciated.
ggplot(fitbit_data, aes(x = Date, y = Steps)) +
geom_bar(stat = "identity", fill = "green") +
labs(title = "My Steps", subtitle = " June - Dec 2019",
x = " Date", y = "Steps") +
scale_x_date(
date_labels = "%b\n%Y",
date_breaks = "1 month",
limits = c(as.Date("2019-06-01"), as.Date("2019-12-31"))
)
Likely the data is converted to factor, thus ggplot shows a categorical y-axis, that then appears with overlapping labels that look like those grey columns.
When reading the data make sure to use
df= read.table(...,
# assign appropriate data types by using
colClasses = c(...),
... ,
# it can also be adviseable to use
stringsAsFactors = FALSE)
I'm having a very, very tough time getting the x-axis to look correct for my graphs.
Here is my data (generated via dput()):
df <- structure(list(Month = structure(1:12, .Label = c("2011-07-31", "2011-08-31", "2011-09-30", "2011-10-31", "2011-11-30", "2011-12-31", "2012-01-31", "2012-02-29", "2012-03-31", "2012-04-30", "2012-05-31", "2012-06-30"), class = "factor"), AvgVisits = c(6.98655104580674,7.66045407330464, 7.69761337479304, 7.54387561322994, 7.24483848458728, 6.32001400498928, 6.66794871794872, 7.207780853854, 7.60281201431308, 6.70113837397123, 6.57634103019538, 6.75321935568936)), .Names = c("Month","AvgVisits"), row.names = c(NA, -12L), class = "data.frame")
Here is the chart I am trying to graph:
ggplot(df, aes(x = Month, y = AvgVisits)) +
geom_bar() +
theme_bw() +
labs(x = "Month", y = "Average Visits per User")
That chart works fine - but, if I want to adjust the formatting of the date, I believe I should add this:
scale_x_date(labels = date_format("%m-%Y"))
I'm trying to make it so the date labels are 'MMM-YYYY'
ggplot(df, aes(x = Month, y = AvgVisits)) +
geom_bar() +
theme_bw() +
labs(x = "Month", y = "Average Visits per User") +
scale_x_date(labels = date_format("%m-%Y"))
When I plot that, I continue to get this error:
stat_bin: binwidth defaulted to range/30. Use 'binwidth = x' to adjust this.
Despite hours of research on formatting of geom_line and geom_bar, I can't fix it. Can anyone explain what I'm doing wrong?
Edit: As a follow-up thought: Can you use date as a factor, or should you use as.Date on a date column?
To show months as Jan 2017 Feb 2017 etc:
scale_x_date(date_breaks = "1 month", date_labels = "%b %Y")
Angle the dates if they take up too much space:
theme(axis.text.x=element_text(angle=60, hjust=1))
Can you use date as a factor?
Yes, but you probably shouldn't.
...or should you use as.Date on a date column?
Yes.
Which leads us to this:
library(scales)
df$Month <- as.Date(df$Month)
ggplot(df, aes(x = Month, y = AvgVisits)) +
geom_bar(stat = "identity") +
theme_bw() +
labs(x = "Month", y = "Average Visits per User") +
scale_x_date(labels = date_format("%m-%Y"))
in which I've added stat = "identity" to your geom_bar call.
In addition, the message about the binwidth wasn't an error. An error will actually say "Error" in it, and similarly a warning will always say "Warning" in it. Otherwise it's just a message.
I am sure this is an easy one but I couldn't find a solution from other posts.
If I run this:
test <- data.frame(dates = as.Date(c("2016-10-31","2016-11-30", "2016-12-31", "2017-01-31")),
values = c(1, 2, 3, 4))
ggplot(test, aes(x = dates, y = values)) +
geom_bar(position="stack", stat = "identity") +
scale_x_date(breaks = date_breaks("1 months"),labels = date_format("%b-%y"))
I get this:
As you can appreciate, all the dates on the X axis are moved forward to the following month.
I tried to use the scales package as suggested elsewhere but it didn't change a thing.
I can get away with this by tweaking the date using:
test$dates <- as.Date(format(test$dates, "%Y-%m-1"))
which delivers this (without using the scale_x_date bit):
but I am sure there is an elegant way to circumvent the problem.
I have run into this problem myself when doing monthly time series charts. My solution: add in a vector of dates into the "breaks = " section.
I.e.
scale_x_date(breaks = test$dates, labels = date_format("%b-%y"))
Note: When I tried "data_breaks" (like your code), I was not able to get it to work under a number of different permutations. The vector of dates only works with "breaks", not "data_breaks"
ggplot(test, aes(x = dates, y = values)) +
geom_bar(position="stack", stat = "identity") +
scale_x_date(breaks = test$dates, labels = date_format("%b-%y"))
P.s. This is my first attempt at answering a question here. I know that the question is old, but hopefully this will help someone!
The labels are correct when you transform dates with as.POSIXct and use scale_x_datetime instead of scale_x_date (no idea why though):
ggplot(test, aes(x = as.POSIXct(dates), y = values)) +
geom_bar(position="stack", stat = "identity") +
scale_x_datetime(breaks = date_breaks("1 months"), labels = date_format("%b-%y"))
Problem
I would like to format my X-axis (time) so that the weekends are clearly visible. I would like to display the date as well as the day of the week.
Current situation
I do this with (full code below)
scale_x_date(breaks=myData$timestamp,
labels=paste(
substr(format(myData$timestamp, "%a"),1,1),
format(myData$timestamp, "%d"),
sep="\n")
)
which gives me
Wanted situation
I would rather have a one letter abbreviation for the weekdays since it became a bit tight there.. Also, I'd like to color sundays (and holidays really) in red. Here's what I mean (made with GIMP). Note how the first Monday and last Friday was added by using
scale_x_date(breaks = "1 day",
minor_breaks = "1 days",
labels = date_format("%a\n%d"),
name="")
However, then I get a three letter abbreviation of the weekdays, which I removed in GIMP.
Here is the complete code for this example.
library(ggplot2)
library(scales)
library(reshape2)
minimumTime <- as.Date("2014-07-01")
maximumTime <- as.Date("2014-07-31")
x <- seq(minimumTime,maximumTime, by="1 day")
y1 <- sin(as.numeric(x)/3)
y2 <- cos(as.numeric(x)/3)
myData <- data.frame(timestamp=x, y1=y1, y2=y2)
myData <- melt(myData, id.vars="timestamp")
rects <- data.frame(saturdays=myData[weekdays(myData$timestamp) == "Saturday","timestamp"]-0.5, sundays = myData[weekdays(myData$timestamp) == "Saturday","timestamp"]+1.5)
myPlot <- ggplot() +
geom_rect(data=rects, aes(xmin=saturdays, xmax=sundays,ymin=-Inf, ymax=Inf), alpha=0.1) +
geom_line(data=myData, aes(x=timestamp, y=value, colour=variable,size=1)) +
geom_point(data=myData, aes(x=timestamp, y=value, colour=variable,size=2)) +
scale_x_date(breaks=myData$timestamp, labels=paste(substr(format(myData$timestamp, "%a"),1,1),format(myData$timestamp, "%d"),sep="\n")) +
#scale_x_date(breaks = "1 day", minor_breaks = "1 days", labels = date_format("%a\n%d"), name="") +
scale_size_continuous(range = c(1.5,5), guide=FALSE)
So to sum up:
Is there a way to color specific breaks in another color?
Is there a way change to the labels manually and still have them for the Monday and
the Friday at the beginning and the end in this case?
Also, if there's a way to have the lines of each label centered, that would be
awesome :)
Thank you!
You can use your custom formater for labels also using breaks="1 day" argument, you just have to use function(x) after labels= and replace myDate$timestamp with x. This will also solve the third problem.
+ scale_x_date(breaks="1 day",
labels= function(x) paste(substr(format(x, "%a"),1,1),format(x, "%d"),sep="\n"))
Or you can make your transformation as seperate function and then use it for labels=.
my_date_trans<-function(x) {
paste(substr(format(x, "%a"),1,1),format(x, "%d"),sep="\n")
}
+ scale_x_date(breaks="1 day",labels=my_date_trans)
To change colors for labels you should use theme() and axis.text.x=. Here I using vector of colors that contains 6 time black and then red as your scale starts with Monday. Those colors are then repeated.
ggplot() +
geom_rect(data=rects, aes(xmin=saturdays, xmax=sundays,ymin=-Inf, ymax=Inf), alpha=0.1) +
geom_line(data=myData, aes(x=timestamp, y=value, colour=variable,size=1)) +
geom_point(data=myData, aes(x=timestamp, y=value, colour=variable,size=2)) +
scale_x_date(breaks="1 day",labels=my_date_trans)+
scale_size_continuous(range = c(1.5,5), guide=FALSE)+
theme(axis.text.x=element_text(color=c(rep("black",6),"red")))