I'd like to make a plot with every day labeled on the x axis.
Here is my data
my_data <- read.table(text="day value
11/15/19 0.23633
11/16/19 0.28485
11/17/19 0.63127
11/18/19 0.15434
11/19/19 0.47964
11/20/19 0.65967
11/21/19 0.48741
11/22/19 0.84541
11/23/19 0.10123
11/24/19 0.78169
11/25/19 0.23189
11/26/19 0.86665
11/27/19 0.55184
11/28/19 0.81410
11/29/19 0.25821
11/30/19 0.23576
12/1/19 0.46397
12/2/19 0.55764
12/3/19 0.95645
12/4/19 0.63954
12/5/19 0.76766
12/7/19 0.74505
12/8/19 0.65515
12/9/19 0.58222
12/10/19 0.17294", header=TRUE, stringsAsFactors=FALSE)
Here is my code
my_data %>%
ggplot(aes(day, value)) +
geom_line() +
scale_x_continuous(breaks = seq(1, nrow(my_data)),
labels = my_data$day)
It gives me this error: Error in as.Date.numeric(value) : 'origin' must be supplied
I'd like to make it so that every day is represented on the x axis and by default it only does a few of the days that are included in this range of data.
Try to use scale_x_date instead of scale_x_continuous
my_data %>%
ggplot(aes(x = mdy(day), value)) +
geom_line() +
scale_x_date(date_breaks = "1 day")+
theme(axis.text.x = element_text(angle = 45, hjust = 1))
You can use lubridate to convert the data to proper date format:
library(lubridate)
my_data %>%
mutate(day = mdy(day)) %>%
ggplot(aes(day, value)) +
geom_line() +
scale_x_date(date_breaks = "1 day") +
theme(axis.text.x = element_text(angle=90, vjust=0.5))
Related
How do I plot each year as a separate line in ggplot2 I tried the below code but it seems to plot continuous as a single plot.
library(ggplot2)
# Dummy data
data <- data.frame(
Date = c(as.Date("2017-01-14") - 0:13,as.Date("2016-01-14") - 0:13),
value = runif(28)
)
#data$Date <- strptime(data$Date, "%Y-%m-%d" )
data$Year <- as.character(year(data$Date))
data$Year <- factor(data$Year)
ggplot(data) + geom_line(aes(x = Date, y = value, group=Year, color=Year)) +
scale_x_date(date_breaks = "1 day", date_labels = "%d-%m-%y") +
theme(axis.text.x = element_text(angle = 90))
But I want each year to be a separate graph in the same plot.
something like below
Try this approach formating day and month in your date. You got a mess in your plot because of the different year in your date variable. Setting format can help you. Here the code:
library(ggplot2)
library(lubridate)
# Dummy data
data <- data.frame(
Date = c(as.Date("2017-01-14") - 0:13,as.Date("2016-01-14") - 0:13),
value = runif(28)
)
data$Year <- as.character(year(data$Date))
data$Year <- factor(data$Year)
#Format month
data$MonthDay <- format(data$Date,'%b-%d')
#Plot
ggplot(data) + geom_line(aes(x = MonthDay, y = value, group=Year, color=Year)) +
theme_bw()+
theme(axis.text.x = element_text(angle = 90))
Output:
I have the dataframe below :
name<-c("John","John","John","John2","John2","John2")
Dealer<-c("ASD","ASD","ASD","ASDG","ASDF","ASD")
Date<-c("2020-01-03","2020-01-04","2020-01-05","2020-02-03","2020-02-04","2020-02-05")
dataset<-data.frame(name,Dealer,Date)
and I want a monthly trend visualization of the count of name , filterable by Dealer.
I have reached to the code below but I do not know how to find the count of each name. I feel that I have to convert my dataframe somehow.
library(ggplot2)
ggplot(dataset, aes(x = Date, y = , color = Dealer)) +
geom_line() +
scale_x_date(date_breaks = "1 months", date_labels = "%b '%y") +
theme_minimal()
*edited dataframe with a dataset with all values being the same in name and Dealer
name<-c("John","John","John","John","John","John","John")
Dealer<-c("ASD","ASD","ASD","ASD","ASD","ASD","ASD")
Date<-c("2020-01-03","2020-01-04","2020-01-05","2020-01-06","2020-01-07","2020-01-08","2020-01-09")
dataset<-data.frame(name,Dealer,Date)
Maybe something like this:
library(tidyverse); library(lubridate)
dataset %>%
# Convert "Date" into date form
mutate(Date = ymd(Date)) %>%
# Count how many occasions of each name-Dealer-month combo
count(name, Dealer, month = floor_date(Date, "month")) %>%
# Add rows for missing months for each existing name-Dealer combo
complete(month, nesting(name, Dealer), fill = list(n = 0)) %>%
ggplot(aes(month, n, color = name)) +
geom_line() +
scale_x_date(date_breaks = "1 months", date_labels = "%b\n'%y") +
theme_minimal() +
facet_wrap(~Dealer)
Hi I have this input file
http://www.mediafire.com/file/a4yda7zmwvpd9zi/data.xlsx/file
MIN and MAX columns are Date type in the xls file and also after as.Date the Class is Date, the type is double as it should be.. but when I run the following code
library(ggplot2)
library(readxl)
out <- read_xlsx("C:/data.xlsx")
out
out$MIN <- as.Date(out$MIN)
out$MAX <- as.Date(out$MAX)
class(out$MIN)
#out$MIN <- as.Date(out$MIN, format = "%d/%m/%Y")
library(dplyr)
out %>%
group_by(SEX) %>%
tidyr::gather(key, value, -SEX) %>%
ggplot(aes(SEX, value)) +
geom_line(aes(color = SEX)) +
coord_flip() +
scale_y_date(breaks = c(out$MIN, out$MAX)) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
out
I keep getting the error date_trans works with objects of class Date only
I tried different formats.. even changed the excel original data types to different date formats but keep getting the same error..
You could try:
out %>%
tidyr::gather(key, value, -one_of(c("ID", "SEX"))) %>%
ggplot(aes(ID, value, group = ID)) +
geom_line(aes(color = SEX)) +
coord_flip() +
scale_y_date(breaks = seq(min(out$MIN), max(out$MAX), by = "year")) +
theme(axis.text.x = element_text(angle = 90, hjust = 1))
Though I doubt the usefulness of such charts, and how you'd solve the scale for dates (I made a sequence of years from the minimum to maximum), but that's up to you.
I want to show every second of x-axis label list in the presentation.
Simplified code example in the following and its output in Fig. 1 where four Dates shown but #2 and #4 should be skipped.
# https://stackoverflow.com/a/6638722/54964
require(ggplot2)
my.dates = as.Date(c("2011-07-22","2011-07-23",
"2011-07-24","2011-07-28","2011-07-29"))
my.vals = c(5,6,8,7,3)
my.data <- data.frame(date =my.dates, vals = my.vals)
plot(my.dates, my.vals)
p <- ggplot(data = my.data, aes(date,vals))+ geom_line(size = 1.5)
Expected output: skip dates second and fourth.
Actual code
Actual code where due to rev(Vars) logic, I cannot apply as.Date to the values in each category; the variable molten has a column Dates
p <- ggplot(molten, aes(x = rev(Vars), y = value)) +
geom_bar(aes(fill=variable), stat = "identity", position="dodge") +
facet_wrap( ~ variable, scales="free") +
scale_x_discrete("Column name dates", labels = rev(Dates))
Expected output: skip #2,#4, ... values in each category.
I thought here changing scale_x_discrete to scale_x_continuous and having a break sequence breaks = seq(1,length(Dates),2)) in scale_x_continuous but it fails because of the following error.
Error: `breaks` and `labels` must have the same length
Proposal based Juan's comments
Code
ggplot(data = my.data, aes(as.numeric(date), vals)) +
geom_line(size = 1.5) +
scale_x_continuous(breaks = pretty(as.numeric(rev(my.data$date)), n = 5))
Output
Error: Discrete value supplied to continuous scale
Testing EricWatt's proposal application into Actual code
Code proposal
p <- ggplot(molten, aes(x = rev(Vars), y = value)) +
geom_bar(aes(fill=variable), stat = "identity", position="dodge") +
facet_wrap( ~ variable, scales="free") +
scale_x_discrete("My dates", breaks = Dates[seq(1, length(Dates), by = 2)], labels = rev(Dates))
Output
Error: `breaks` and `labels` must have the same length
If you have scale_x_discrete("My dates", breaks = Dates[seq(1, length(Dates), by = 2)]), you get x-axis without any labels so blank.
Fig. 1 Output of the simplified code example,
Fig. 2 Output of EricWatt's first proposal
OS: Debian 9
R: 3.4.0
This works with your simplified example. Without your molten data.frame it's hard to check it against your more complicated plot.
ggplot(data = my.data, aes(date, vals)) +
geom_line(size = 1.5) +
scale_x_date(breaks = my.data$date[seq(1, length(my.data$date), by = 2)])
Basically, use scale_x_date which will likely handle any strange date to numeric conversions for you.
My solution eventually on the actual code motivated by the other linked thread and EricWatt's answer
# Test data of actual data here # https://stackoverflow.com/q/45130082/54964
ggplot(data = molten, aes(x = as.Date(Time.data, format = "%d.%m.%Y"), y = value)) +
geom_bar(aes(fill = variable), stat = "identity", position = "dodge") +
facet_wrap( ~ variable, scales="free") +
theme_bw() + # has to be before axis text manipulations because disables their effect otherwise
theme(axis.text.x = element_text(angle = 90, hjust=1),
text = element_text(size=10)) +
scale_x_date(date_breaks = "2 days", date_labels = "%d.%m.%Y")
This code produces a single boxplot:
df <- data.frame(value = rnorm(62), my.date = seq(as.Date("2013-12-01"), as.Date("2014-01-31"), by="1 day"))
library(ggplot2)
ggplot(df, aes(as.Date(my.date), value)) + geom_boxplot() + scale_x_date(minor_breaks = "1 week", labels = date_format("%W\n%b"))
How can I produce a plot that has single boxplots for each week between 1 December and 31 January? So within the single plot, there should be about 8 boxplots. Would prefer solution that uses either ggplot() or scale_x_date().
One option is to transform your date before using ggplot
library(ggplot2)
df <- data.frame(value = rnorm(62),
my.date = seq(as.Date("2013-12-01"), as.Date("2014-01-31"), by="1 day"))
weeks <- format(df$my.date, "%Y/%W")
weeks <- factor(weeks, levels = unique(weeks))
ggplot(df, aes(weeks, value)) +
geom_boxplot()
library(ggplot2)
ggplot(df, aes(format(as.Date(my.date), "%W\n%b"), value)) + geom_boxplot()
Edit:
To order the dates:
ggplot(df, aes(reorder(format(as.Date(my.date), "%W\n%b"),
as.Date(my.date)),
value)) +
geom_boxplot()
This fulfils #luciano's request to retain functionality of scale_x_date
library('scales')
library(ggplot2)
df <- data.frame(value = rnorm(62), my.date = seq(as.Date("2013-12-01"), as.Date("2014-01-31"), by="1 day"))
ggplot(df, aes(x=as.Date(my.date), y=value, group=format(as.Date(my.date),"%W-%b"))) + geom_boxplot() + scale_x_date(date_breaks = "1 week", date_labels="%Y-%b-%d")
Alternatively, if you don't want the data grouped by week# - which gives you the split around most new years - you can group by week ending Sundays as below. Adjusting from the Sunday weekending, to say Friday, can be achieved with some such code
ceiling_date(x, "week") + ifelse(weekdays(x) %in% c("Saturday", "Sunday"), 5, -2)
ggplot(df, aes(x=as.Date(my.date), y=value, group=ceiling_date(my.date, "week"))) + geom_boxplot() + scale_x_date(date_breaks = "1 week", date_labels="%Y-%b-%d")