I have tried to read through stackoverflow, blogs, books etc but have been unable to find the answer on plotting time in the x-axis in the following format(HH:MM:SS.000) in R and another quantity on the y-axis. I have the following dataset:
Time EcNo
12:54:09.000 -14.47
12:54:10.000 -17.96
12:54:11.000 -15.97
12:54:12.000 -14.61
12:54:13.000 -12.68
12:54:14.000 -10.73
12:54:15.000 -10.54
12:54:16.000 -11.62
12:54:17.000 -12.49
12:54:18.000 -11.12
How would I plot EcNo on Yaxis vs Time(x axis) in the format HH:MM:SS.000 as shown above.
I honestly would appreciate some help.
many thanks
You may also try ggplot:
library(ggplot2)
df$time <- as.POSIXct(strptime(df$Time, format="%H:%M:%S"))
# Automatic scale selection
ggplot(data = df, aes(x = time, y = EcNo)) + geom_point()
scale_x_datetime is a ggplot function, but for the nice arguments date_breaks, and date_format you need package scales:
library(scales)
ggplot(data = df, aes(x = time, y = EcNo)) + geom_point() +
scale_x_datetime(breaks = date_breaks("1 sec"), labels = date_format("%S"))
ggplot(data = df, aes(x = time, y = EcNo)) + geom_point() +
scale_x_datetime(breaks = date_breaks("1 sec"), labels = date_format("%OS3"))
ggplot(data = df, aes(x = time, y = EcNo)) + geom_point() +
scale_x_datetime(breaks = date_breaks("4 sec"), labels = date_format("%M:%S"))
plot(strptime(dta$Time, format="%H:%M:%S"), dta$EcNo, xaxt="n")
axis(1, at=as.numeric(strptime(dta$Time, format="%H:%M:%S")),
labels=strftime( strptime(dta$Time, format="%H:%M:%S"),format="%H:%M:%S"))
df <- data.frame(
Time=c('12:54:09.000','12:54:10.000','12:54:11.000','12:54:12.000','12:54:13.000','12:54:14.000','12:54:15.000','12:54:16.000','12:54:17.000','12:54:18.000'),
EcNo=c(-14.47,-17.96,-15.97,-14.61,-12.68,-10.73,-10.54,-11.62,-12.49,-11.12)
)
op <- options(digits.secs=3)
plot(as.POSIXct(df$Time,format="%H:%M:%OS"),df$EcNo,xaxt="n")
axis.POSIXct(1, as.POSIXct(df$Time,format="%H:%M:%OS"), format="%H:%M:%OS")
Related
I'm plotting HH:MM:SS on the y-axis against YYYY:MM on the x-axis, but am having issues trying to use scale_y_reverse with scale_y_time together.
sample data below:
library(hms)
library(ggplot2)
df_stack <- data.frame(yr_mn = rep(c("2020-01", "2020-02", "2020-03", "2020-04"),2),
timept_type = c(rep("A",4),rep("B",4)),
timept = as_hms(c("08:00:00", "09:10:00", "11:05:30", "10:45:00", "09:30:10", "10:00:00", "11:25:00", "08:40:00")))
df_stack %>%
ggplot(., aes(x=yr_mn, y=timept, color=timept, fill=timept)) +
geom_point() +
geom_line(aes(group=1))+
facet_wrap(vars(timept_type), scales="free", ncol=2) +
scale_y_time(limits = c(as.POSIXct(as_hms("07:00:00")), as.POSIXct(as_hms("11:30:00")))) +
scale_y_reverse() # this cause the y-axis labels to no longer be in hh:mm:ss format
If I comment out the last line scale_y_reverse() then the graph looks fine, but if I include it, the scale_y_reverse seems to convert the HH:MM:SS into seconds. I have no idea if it's something I'm doing incorrectly or if there's a built-in method within scale_y_time to resolve this. Thanks!
You can omit the scale_y_time and supply functions to scale_y_reverse to generate the labels and the breaks.
df_stack %>%
ggplot(aes(yr_mn, timept, color = timept, fill = timept)) +
geom_point() +
geom_line(aes(group = 1)) +
facet_wrap(vars(timept_type), scales = "free", ncol = 2) +
scale_y_reverse(labels = function(x) as_hms(x),
breaks = seq(as.numeric(as_hms("07:00:00")),
as.numeric(as_hms("11:30:00")),
1800))
Result:
After digging into the code for scale_x_reverse() and scale_x_time(), I've made a simplified version for my data (where x is time, and y is value).
Add a - in front of the variable to be reversed in the aesthetic, and add a reverse label function to scale_x_time(labels = function(x) -x)
ggplot(df, aes(x = -clock, y = points)) +
geom_point() +
scale_x_time(labels = function(x) -x)
xlab("Clock") + ylab("Points")
Reversing the limits may easier and less error-prone.
ggplot(df, aes(x = clock, y = points)) +
geom_point() +
scale_x_time(limits = c(12*60*60,0)) # in seconds
xlab("Clock") + ylab("Points")
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")
I want to define what is written on the ticks of the y-axis in a ggplot plot.
The particular problem is that I want the y-axis to show one decimal point. Instead of 25 it should read 25.0. I can of course hard-code it in by hand; but this is extremely tedious. (The code below does what it is supposed to do)
library(ggplot2)
DF <- data.frame(c(0:100),c(0:100)) colnames(DF)=c("x","y")
pl <- ggplot(data = DF, aes(x = x, y = y)) + geom_point() +
scale_y_continuous(breaks = c(0,25.0,50.0,75.0,100.0),
labels = c("0","25.0","50.0","75.0","100.0"))
Is there a way to format the x and y axis without having to type the exact labels in myself?
Instead of labels = c("0","25.0","50.0","75.0","100.0") there should be a command that whatever the ticks on the y-axis, the labeling should be done with one digit after the decimal point.
How about:
pl <- ggplot(data = DF, aes(x = x, y = y)) +
geom_point() +
scale_y_continuous(labels = function(x) format(x, nsmall = 1))
Try format:
pl <- ggplot(data = DF, aes(x = x, y = y)) + geom_point() +
scale_y_continuous(breaks = c(0,25.0,50.0,75.0,100.0),
labels = format(c("0","25","50","75","100"),nsmall=1))
I'm trying to make a simple Date * temperature heatmap (?raster graph?) that shows temperature over time based on binned temperature groups. Something like this but only along the date axis (no time variable. I'd prefer to use ggplot, but keep runnning astray. The graph the data produces is headed in the right direction, but I can't figure out how to get rid of the y-axis. I'd appreciate any help
dat <- data.frame(temp = sample(20,100, replace=TRUE), date=seq(as.Date("2011-07-01"), by=1, len=100))
p <- ggplot(dat, aes(date, temp)) + geom_tile(aes(fill = temp)) + scale_fill_gradient(low = "blue", high = "red")
Thanks!
So you don't want to map temp on the y axis?
Well then you could use a fixed value for y and remove the rest of the y-axis:
dat <- data.frame(temp = sample(20,100, replace=TRUE),
date=seq(as.Date("2011-07-01"), by=1, len=100))
require(ggplot2)
ggplot(dat, aes(x = date, y = 1)) +
geom_tile(aes(fill = temp)) +
scale_fill_gradient(low = "blue", high = "red") +
labs(y = NULL) +
scale_y_continuous(breaks = NULL)
You could also try doing something like the plot below with the metvurst package.
http://i.imgur.com/8Js1Uz7.png
dat <- data.frame(temp = sample(20,60, replace=TRUE),
date=seq(as.POSIXct("2011-01-01 00:00"), by=3600, len=8760))
dat$year <- as.numeric(format(dat$date,"%Y"))
dat$month <- as.numeric(format(dat$date,"%m"))
# Install and load metvurst library
install_github('metvurst', 'tim-salabim')
library(metvurst)
plot.air.temp <- strip(x = dat$temp,
date = dat$date,
cond = dat$year,
arrange = "long",
colour = colorRampPalette(rev(brewer.pal(11, "Spectral"))),
main = "Daily Air Temperatures\n\nTemperature [°C]")
plot.air.temp
I have tried to read through stackoverflow, blogs, books etc but have been unable to find the answer on plotting time in the x-axis in the following format(HH:MM:SS.000) in R and another quantity on the y-axis. I have the following dataset:
Time EcNo
12:54:09.000 -14.47
12:54:10.000 -17.96
12:54:11.000 -15.97
12:54:12.000 -14.61
12:54:13.000 -12.68
12:54:14.000 -10.73
12:54:15.000 -10.54
12:54:16.000 -11.62
12:54:17.000 -12.49
12:54:18.000 -11.12
How would I plot EcNo on Yaxis vs Time(x axis) in the format HH:MM:SS.000 as shown above.
I honestly would appreciate some help.
many thanks
You may also try ggplot:
library(ggplot2)
df$time <- as.POSIXct(strptime(df$Time, format="%H:%M:%S"))
# Automatic scale selection
ggplot(data = df, aes(x = time, y = EcNo)) + geom_point()
scale_x_datetime is a ggplot function, but for the nice arguments date_breaks, and date_format you need package scales:
library(scales)
ggplot(data = df, aes(x = time, y = EcNo)) + geom_point() +
scale_x_datetime(breaks = date_breaks("1 sec"), labels = date_format("%S"))
ggplot(data = df, aes(x = time, y = EcNo)) + geom_point() +
scale_x_datetime(breaks = date_breaks("1 sec"), labels = date_format("%OS3"))
ggplot(data = df, aes(x = time, y = EcNo)) + geom_point() +
scale_x_datetime(breaks = date_breaks("4 sec"), labels = date_format("%M:%S"))
plot(strptime(dta$Time, format="%H:%M:%S"), dta$EcNo, xaxt="n")
axis(1, at=as.numeric(strptime(dta$Time, format="%H:%M:%S")),
labels=strftime( strptime(dta$Time, format="%H:%M:%S"),format="%H:%M:%S"))
df <- data.frame(
Time=c('12:54:09.000','12:54:10.000','12:54:11.000','12:54:12.000','12:54:13.000','12:54:14.000','12:54:15.000','12:54:16.000','12:54:17.000','12:54:18.000'),
EcNo=c(-14.47,-17.96,-15.97,-14.61,-12.68,-10.73,-10.54,-11.62,-12.49,-11.12)
)
op <- options(digits.secs=3)
plot(as.POSIXct(df$Time,format="%H:%M:%OS"),df$EcNo,xaxt="n")
axis.POSIXct(1, as.POSIXct(df$Time,format="%H:%M:%OS"), format="%H:%M:%OS")