I am looking to set x-axis limits on a rather simple time series plot in R.
My plot produces limits that are 6 hours ahead of my time zone (plot would start and end at 14:00:00 in the example below).
I am currently in "America/Denver".
My data was previously plotted so that everything was shifted 6 hours back but I was able to align that properly on the x-axis, but now the bounds/limits of the x-axis are still a problem.
date_format <- function(format = "%b %d - %H:%M") {function(x) format(x, format)}
lims <- as.POSIXct(strptime(c("2021-05-04 08:00:00","2021-05-08 08:00:00"), format = "%Y-%m-%d %H:%M"))
combo_ch1short <- ggplot(data = data_combo_ch1short, aes(x = DateTime, y = Z.kOhm, color = probe.pair.name)) +
scale_x_datetime(labels = date_format(), limits = lims, date_breaks = "12 hours") + ...
Sorry, pretty new to this. Any help is GREATLY appreciated!
Edit:
data_combo_ch1short:
Time probe.pair.name DateTime Z.kOhm
1617890878 ch_1_ch_2 2021-04-12 17:52:32 5228.69
1617890878 ch_1_ch_3 2021-04-12 17:52:32 5031.88
1618251752 ch_1_ch_2 2021-04-12 18:22:32 4089.37
1618251752 ch_1_ch_3 2021-04-12 18:22:32 4231.90
...
You can create lims in any timezone by specifying the timezone in tz argument.
lims <- as.POSIXct(c("2021-05-04 08:00:00","2021-05-08 08:00:00"), tz = 'US/Mountain')
I have some data, and I want to use some variables from stat_count() to label a bar plot.
This is what I want to do:
library(ggplot2)
library(scales)
percent_and_count <- function(pct, cnt){
paste0(percent(pct), ' (', cnt, ')')
}
ggplot(aes(x=Type)) +
stat_count(aes(y=(..prop))) +
geom_text(aes(y=(..prop..), label=percent_and_count(..prop.., ..count))),
stat='count')
However, I get this error, since it can't find the function in what I assume is either some base packages or the data frame:
Error in eval(expr, envir, enclos) : could not find function "percent_and_count"
I get this error if I do percent(..prop..) as well, although it is fine with scales::percent(..prop..). I did not load my function from a package.
If all else fails, I can do
geom_text(aes(y=(..prop..), label=utils::getAnywhere('percent_and_count')$objs[[1]]((..prop..),(..count..))))
But this seems needlessly roundabout for what should be a stupidly simple task.
You can use bquote and aes_:
# Sample data
set.seed(2017);
df <- data.frame(
Type = sample(6, 100, replace = T)
);
library(ggplot2);
library(scales);
# Your custom function
percent_and_count <- function(pct, cnt){
paste0(percent(pct), ' (', cnt, ')')
}
ggplot(df, aes(x = Type)) +
stat_count(aes(y = ..prop..)) +
geom_text(
stat = "count",
aes_(
y = ~(..prop..),
label = bquote(.(percent_and_count)((..prop..), (..count..)))))
Explanation: bquote(.(percent_and_count)(...)) ensures that percent_and_count is found (as terms .(...) are evaluated in the parent environment). We then use aes_ to ensure that quoted expressions (either with ~ or bquote) are properly evaluated.
Still not pretty, but probably more straighforward than using utils::getAnywhere.
This question already has answers here:
Time series plot gets offset by 2 hours if scale_x_datetime is used
(2 answers)
Closed 6 years ago.
I have a question on formatting the x axis as time.
This is a sample of my data:
dput(x)
structure(list(Sample = c("BK01", "BK02", "BK03", "BK04", "BK05",
"BK06", "BK07", "BK08", "BK09", "BK10", "BK11", "BK12", "BK13",
"BK14", "BK15", "BK16", "BK17", "BK18", "BK19", "BK20", "BK21",
"BK22", "BK23", "BK24", "BK25", "BK26", "BK27", "BK28", "BK29",
"BK30", "BK31", "BK32", "BK33"), Breath.d13C = c(-25.62, -27.45,
-26.87, -25.21, -26.01, -24.33, -24.45, -23.73, -25.05, -26.11,
-27, -26.28, -24.62, -26.96, -24.55, -24.52, -21.24, -26.18,
-24.82, -26.12, -27.28, -26.5, -24.46, -22.83, -27.28, -25.55,
-27.12, -24.46, -23.07, -28.35, NA, -25.98, -26.64), Chms = structure(c(1470047400,
1470048300, 1470048300, 1470049200, 1470050100, 1470050100, 1470040200,
1470041100, 1470040200, 1470041100, 1470065400, 1470063600, 1470063600,
1470064500, 1470061800, 1470045600, 1470045600, 1470046500, 1470047400,
1470066300, 1470060000, 1470058200, 1470057300, 1470047400, 1470042000,
1470042000, 1470041100, 1470041100, 1470040200, 1470043800, NA,
1470060000, 1470039300), class = c("POSIXct", "POSIXt"), tzone = "")), class = "data.frame", row.names = c(NA,
-33L), .Names = c("Sample", "Breath.d13C", "Chms"))
I want to use ggplot2 to build a graph of Breath.d13C vs Chms (Collection Time).
library(ggplot2)
ggplot(x, aes(x=Chms,y=Breath.d13C)) +
geom_point() +
scale_y_continuous(name=expression(delta^13*C["Breath"]*" "("\u2030")),
limits=c(-30,-10),
breaks=seq(-30,-10,5),
labels=fmt_decimals(1)) +
scale_x_datetime(name="Collection Time",
labels = date_format("%H:00",tz="UTC"),
date_breaks = "1 hour") +
my_theme
This code gives me . However the times are off by an hour.
I can see this by checking the Chms column or by using the normal R plots
with this code:
plot(x$Chms,x$Breath.d13C,cex=0.8)
The two plots use the same data set, so I have no idea what's causing the error on ggplot2. I'd like to keep using it, though. Any ideas on what am I doing wrong?
Thank you in advance
You need to specify the time zone in scale_x_datetime.
The function date_format() is by default set to "UTC". Therefore, your labels are converted to UTC. To use the time zone e.g. I used "Europe/London" (to get your desired output), you can do the following in your ggplot code: labels = date_format("%H:%M", tz = "Europe/London")
But firstly in order to run your code I also had to define what you specified in your code as fmt_decimals So I used this function given by #joran:
fmt_dcimals <- function(decimals=0){
# return a function responpsible for formatting the
# axis labels with a given number of decimals
function(x) as.character(round(x,decimals))
}
So your code looks like this:
ggplot(x, aes(x=Chms,y=Breath.d13C)) +
geom_point() +
scale_y_continuous(name=expression(delta^13*C["Breath"]*" "("\u2030")),
limits=c(-30,-10),
breaks=seq(-30,-10,5),
labels=fmt_dcimals(1)) +
scale_x_datetime(name="Collection Time",
labels = date_format("%H:%M", tz = "Europe/London"),
date_breaks = "1 hour")
And output:
The problem lie in the time zone you select, i.e. UTC. You should choose the current time zone. The corrected code is as below
library(ggplot2)
ggplot(x, aes(x=Chms,y=Breath.d13C)) +
geom_point() +
scale_y_continuous(name=expression(delta^13*C["Breath"]*" "
("\u2030")),
limits=c(-30,-10),
breaks=seq(-30,-10,5)) +
scale_x_datetime(name="Collection Time",
labels = date_format("2016-08-01 %H:00",""),
date_breaks = "1 hour")
See the plot as belpw
I want to generate a plot of interest over time using GTrendsR and ggplot2
The plot I want (generated with google trends) is this:
Any help will be much appreciated.
Thanks!
This is the best I was able to get:
library(ggplot2)
library(devtools)
library(GTrendsR)
usr = "my.email"
psw = "my.password"
ch = gConnect(usr, psw)
location = "all"
query = "MOOCs"
MOOCs_trends = gTrends(ch, geo = location, query = query)
MOOCs<-MOOCs_trends[[1]]
MOOCs$moocs<-as.numeric(as.character(MOOCs$moocs))
MOOCs$Week <- as.character(MOOCs$Week)
MOOCs$start <- as.Date(MOOCs$Week)
ggplot(MOOCs[MOOCs$moocs!=0,], aes(start, moocs)) +
geom_line(colour = "blue") +
ylab("Trends") + xlab("") + theme_bw()
I think that to match the graph generated by google I would need to aggregate the data to months instead of weeks... not sure how to do that yet
The object returned by gtrendsR is a list, of which the trend element in a data.frame that you would want to plot.
usr = "my.email"
psw = "my.password"
gconnect(usr, psw)
MOOCs_trends = gtrends('MOOCs')
MOOCsDF <- MOOCs_trends$trend
ggplot(data = MOOCsDF) + geom_line(aes(x=start, y=moocs))
This gives:
Now if you want to aggregate by month, I would suggest using the floor_date function from the lubridate package, in combination with dplyr (note that I am using the chain operator %>% which dplyr re-exports from the magrittr package).
usr = "my.email"
psw = "my.password"
gconnect(usr, psw)
MOOCs_trends = gtrends('MOOCs')
MOOCsDF <- MOOCs_trends
MOOCsDF$start <- floor_date(MOOCsDF$start, unit = 'month')
MOOCsDF %>%
group_by(start) %>%
summarise(moocs = sum(moocs)) %>%
ggplot() + geom_line(aes(x=start, y=moocs))
This gives:
Note 1: The query MOOCs was changed to moocs, by gtrendsR, this is reflected in the y variable that you're plotting.
Note 2: some of the cases of functions have changed (e.g. gtrendsR not GTrendsR), I am using current versions.
This will get you most of the way there. The plot doesn't look quite right, but that's more of a function of the data being a bit different. Here's the necessary conversions to numeric and to dates.
MOOCs<-MOOCs_trends[[1]]
library(ggplot2)
library(plyr)
## Convert to string
MOOCs$Week <- as.character(MOOCs$Week)
MOOCs$moocs <- as.numeric(MOOCs$moocs)
# split the string
MOOCs$start <- unlist(llply(strsplit(MOOCs$Week," - "), function(x) return(x[2])))
MOOCs$start <- as.POSIXlt(MOOCs$start)
ggplot(MOOCs,aes(x=start,y=moocs))+geom_point()+geom_path()
Google might do some smoothing, but this will plot the data you have.
I have a data set and it contains the following variable for date.
dat$Leads_MONTH
[1] "10-Jan" "10-Feb" "10-Mar" "10-Apr" "10-May" "10-Jun" "10-Jul" "10-Aug" "10-Sep" "10-Oct" "10-Nov" "10-Dec" "11-Jan" "11-Feb" "11-Mar" "11-Apr"
[17] "11-May" "11-Jun" "11-Jul" "11-Aug" "11-Sep" "11-Oct" "11-Nov" "11-Dec" "12-Jan" "12-Feb" "12-Mar" "12-Apr" "12-May" "12-Jun" "12-Jul" "12-Aug"
[33] "12-Sep" "12-Oct" "12-Nov" "12-Dec" "13-Jan" "13-Feb" "13-Mar" "13-Apr" "13-May" "13-Jun" "13-Jul"
I want to plot this data on the x axis using ggplot2 but am having some issues with this task. Is there a way to get ggplot2 to format Leads_MONTH as a date format and then plot it using ggplot2.
ggplot(dat, aes(Leads_MONTH, LEADSforester)) +
geom_bar(stat="identity", fill="#336699") +
theme(axis.text.x = element_text(angle = 90, hjust = 1))
The above code produces a plot but the dates on the x axis are not in the write order.
I tried to set the variable as a date but am not having any luck.
> dat$Leads_MONTH <- as.Date(dat$Leads_MONTH)
Error in charToDate(x) :
character string is not in a standard unambiguous format
For the bar plot, you can manually convert Leads_MONTH to factor and specify the levels.
dat <- data.frame(Leads_MONTH = c(
"10-Jan", "10-Feb", "10-Mar", "10-Apr", "10-May", "10-Jun", "10-Jul", "10-Aug", "10-Sep", "10-Oct", "10-Nov", "10-Dec", "11-Jan", "11-Feb", "11-Mar", "11-Apr",
"11-May", "11-Jun", "11-Jul", "11-Aug", "11-Sep", "11-Oct", "11-Nov", "11-Dec", "12-Jan", "12-Feb", "12-Mar", "12-Apr", "12-May", "12-Jun", "12-Jul", "12-Aug",
"12-Sep", "12-Oct", "12-Nov", "12-Dec", "13-Jan", "13-Feb", "13-Mar", "13-Apr", "13-May", "13-Jun", "13-Jul"),
LEADSforester = runif(43))
library(ggplot2)
# Convert Leads_MONTH to factor and specify the levels
dat$Leads_MONTH <- factor(dat$Leads_MONTH, levels = dat$Leads_MONTH)
ggplot(dat, aes(Leads_MONTH, LEADSforester)) +
geom_bar(stat="identity", fill="#336699") +
theme(axis.text.x = element_text(angle = 90, hjust = 1))
If you want to convert into Date class, you need to add day and specify the argument format
as.Date(paste0(dat$Leads_MONTH, '-1'), format = '%y-%b-%d')
Try:
library(zoo)
as.yearmon(dat$Leads_MONTH, format="%y-%b")
To convert them to normal date objects wrap that in as.Date