This question already has an answer here:
How to make scale_x_date week start with Sunday
(1 answer)
Closed 4 years ago.
I have a Shiny app which has both a reactive table, and a ggplot2 line chart (time series) that uses the reactive table as the dataset. I am using scale_x_date(date_breaks = "1 week") in the line chart, and the min and max values of the dates seen change appropriately with the reactive table.
My problem is that I would like the week intervals to be a Saturday (corresponding with the end of our fiscal week, and all the timestamps in the reactive table) but ggplot2 defaults to showing Mondays. How may I change the x-axis to show Saturdays but also scale appropriately in response to the reactive table?
How about like this, borrowing from here but using lubridate to set the lowest break at the preceding Saturday?
library(lubridate)
scale_x_date(breaks = seq(floor_date(min(data.set$week.start), unit = 'week',
week_start = getOption('lubridate.week.start', 6)), max(data.set$week.start),by="week"),
labels = date_format(format = "%Y-%m-%d"))
I just needed
output$fcstlinechart_weekly <- renderPlotly({
p1 <- ggplot2::ggplot(data= my_reactive_table(),
aes(x=Week_End_Date,y=Forecast)+
geom_line()+ scale_x_date(
breaks= unique(data_frame_source_for_reactive_table$Week_End_Date))
p2 <- ggplotly(p1)
p2$elementId <- NULL
p2
})
And the plot rendering was "smart enough" to only show date values that exist in the filtered reactive table.
Related
I'm very new to R. I want to plot graphs by months with ggplot2, but the last dates of the year variable are intertwined on the x-axis. I have attached the image below. Any ideas on how I can adjust the width on the x-axis? Can I also print each year in the date variable? My dates are between 2010-2020.
enter image description here
Updated version. Op seems to be asking for this. The time variable shows the full date ("year-month-day"). Modifying the x-axis using scale_x_date for showing only calendar years:
# example dataset
dt <- data.table(date=as.Date(seq(1,1000,100),origin = "2010-01-01"),var=rnorm(10))
head(dt)
# display only the YEAR
ggplot(dt,aes(y=var,x=date))+geom_point()+
scale_x_date(date_breaks = "1 year", date_labels = "%Y")
# display 6 months intervals
ggplot(dt,aes(y=var,x=date))+geom_point()+
scale_x_date(date_breaks = "6 months", date_labels = "%b %Y")
Older version: the time variable shows only years.
For showing each single year of the data here are two options.
For increasing the width I guess you mean while saving the plot permanently.
Clarification: if you use R Studio you as it seems from the screenshot, you can change the temporary visualization of the plot in many ways using the GUI.
Clarification #2: check ?facet_wrap to see how you can display the facets in multiple rows and columns, that could also help the specific visualization of your plot.
library(ggplot2)
library(data.table)
# create example dataset (no values for 2015)
dt <- data.table(var=rnorm(40),year=sample(c(seq(2010,2014,1),seq(2016,2020,1)),40,replace = T))
# clearly plot each specific year by considering it as factor (2015 not shown)
ggplot(dt,aes(y=var,x=as.factor(year)))+geom_point()+
xlab("Year") # nicer x-axis naming
# clearly plot each specific year by modifying breaks (shows also empty years if present)
ggplot(dt,aes(y=var,x=year))+geom_point()+
scale_x_continuous(breaks = seq(min(dt[,year]),max(dt[,year]),1))
# save the file with exaggerated width (just an example)
ggsave("myfilepath/myfilename.jpg",width=20,height=4,units = "cm")
I have a dataset with a column in string of format hh:mm:ss. I want to create a histogram based on this column in such a way that I can visualize the number of observations between 12 AM and 3 PM in R.
plot_ly(x = (as.numeric(data$Time) * 1000), type = "histogram") %>%
layout(xaxis=list(type="date", tickformat="%H:%M:%S"))
I tried plotting using Plotly but the x-axis is in a different format than expected. Please give suggestions.
One approach could be the use of the hms library
library("hms")
As there was no data provided I generated some random data for an easier understanding. The as_hms() function transforms the values as a difftime vector with a custom class
Count <- c(10,20,30,100,110,110,20,30,50,30)
Time <- c('12:02:01','12:07:38','12:30:42','12:57:21','13:01:09','13:38:36','13:48:43','13:51:33','14:50:22','14:59:59')
Time = as_hms(c(Time))
data = data.frame(Count, Time)
With ggplot you can now easily create an histogram with the number of observations. And if you need explicitly a plotly visualization you can achieve this with the library ggplotly.
p <- ggplot(data=data, aes(x=Time, y=Count)) +
geom_bar(stat="identity")
ggplotly(p)
I would like to create an interactive histogram with dates on the x-axis.
I have used ggplot+ggplotly.
I've read I need to use to pass the proper information using the "text=as.character(mydates)" option and sometimes "tooltips=mytext".
This trick works for other kinds of plots but there is a problem with the histograms, instead of getting a single bar with a single value I get many sub-bars stacked.
I guess the reason is passing "text=as.character(fechas)" produces many values instead of just the class value defining that bar.
How can I solve this problem?
I have tried filtering myself the data but I don't know how to make this the parameters match the parameters used by the histogram, such as where the dates start for each bar.
library(lubridate)
library(ggplot2)
library(ggplotly)
Ejemplo <- data.frame(fechas = dmy("1-1-20")+sample(1:100,100, replace=T),
valores=runif(100))
dibujo <- ggplot(Ejemplo, aes(x=fechas, text=as.character(fechas))) +
theme_bw() + geom_histogram(binwidth=7, fill="darkblue",color="black") +
labs(x="Fecha", y="Nº casos") +
theme(axis.text.x=element_text(angle=60, hjust=1)) +
scale_x_date(date_breaks = "weeks", date_labels = "%d-%m-%Y",
limits=c(dmy("1-1-20"), dmy("1-4-20")))
ggplotly(dibujo)
ggplotly(dibujo, tooltip = "text")
As you can see, the bars are not regular histogram bars but something complex.
Using just ggplot instead of ggplotly shows the same problem, though then you woulnd't need to use the extra "text" parameter.
Presently, feeding as.character(fechas) to the text = ... argument inside of aes() will display the relative counts of distinct dates within each bin. Note the height of the first bar is simply a count of the total number of dates between 6th of January and the 13th of January.
After a thorough reading of your question, it appears you want the maximum date within each weekly interval. In other words, one date should hover over each bar. If you're partial to converting ggplot objects into plotly objects, then I would advise pre-processing the data frame before feeding it to the ggplot() function. First, group by week. Second, pull the desired date by each weekly interval to show as text (i.e., end date). Next, feed this new data frame to ggplot(), but now layer on geom_col(). This will achieve similar output since you're grouping by weekly intervals.
library(dplyr)
library(lubridate)
library(ggplot2)
library(plotly)
set.seed(13)
Ejemplo <- data.frame(fechas = dmy("1-1-20") + sample(1:100, 100, replace = T),
valores = runif(100))
Ejemplo_stat <- Ejemplo %>%
arrange(fechas) %>%
filter(fechas >= ymd("2020-01-01"), fechas <= ymd("2020-04-01")) %>% # specify the limits manually
mutate(week = week(fechas)) %>% # create a week variable
group_by(week) %>% # group by week
summarize(total_days = n(), # total number of distinct days
last_date = max(fechas)) # pull the maximum date within each weekly interval
dibujo <- ggplot(Ejemplo_stat, aes(x = factor(week), y = total_days, text = as.character(last_date))) +
geom_col(fill = "darkblue", color = "black") +
labs(x = "Fecha", y = "Nº casos") +
theme_bw() +
theme(axis.text.x = element_text(angle = 60, hjust = 1)) +
scale_x_discrete(label = function(x) paste("Week", x))
ggplotly(dibujo) # add more text (e.g., week id, total unique dates, and end date)
ggplotly(dibujo, tooltip = "text") # only the end date is revealed
The "end date" is displayed once you hover over each bar, as requested. Note, the value "2020-01-12" is not the last day of the second week. It is the last date observed in the second weekly interval.
The benefit of the preprocessing approach is your ability to modify your grouped data frame, as needed. For example, feel free to limit the date range to a smaller (or larger) subset of weeks, or start your weeks on a different day of the week (e.g., Sunday). Furthermore, if you want more textual options to display, you could also display your total number of unique dates next to each bar, or even display the date ranges for each week.
My data frame consists of one column which as dates in format y/m/d. the other has deaths. The format of the date is posixct. When I plot in R using ggplot the x axis shows days as 1st feb, 15th Feb.. and so on. I want the xaxis with every day as in the data. What do i do?
Thank you
baseplot=ggplot(Data_set,aes(x=Date,y=Cumulative_confirmed_cases,colour="red"))+geom_line(size=1)
baseplot+ scale_x_datetime(date_labels = "%b/%d",limits = c(min,max))+geom_point()
You need to add the date_breaks argument in your scale_x_datetime in order to get all days displayed:
library(ggplot2)
ggplot(Data_set,aes(x=Date,y=Cumulative_confirmed_cases,colour="red"))+
geom_line(size=1) +
scale_x_datetime(date_labels = "%b/%d",limits = c(min,max), date_breaks = "day")+
geom_point()
If this is not working, please provide a reproducible example of your dataset (see: How to make a great R reproducible example)
I am plotting a time series bar chart with a measure for different categories. When I plot the time series bar chart, the width of the bars fills over many dates so that the neighbouring bars touch, even if they are a month apart, but this means that it is unclear which date that bar corresponds to. How do I change the code so that the bars only appear over the date in the underlying dataframe?
I have successfully plotted another time series bar chart with exactly the same ggplot code but different underlying data and so it is unclear to me why this is happening with this particular dataframe.
In this following example, I use a dataframe with only one category for simplicity in highlighting the issue:
data <- data.frame(a = c(as.Date("2019-05-30"), as.Date("2019-06-19")), b = c("FX FORWARD", "FX FORWARD"), c = c(29.2, 74.7))
colnames(data ) <- c("Expiration Date", "Security Type", "Exposure $M")
plot <- ggplot(data , aes(x=`Expiration Date`, y=`Exposure $M`, fill=`Security Type`)) +
geom_bar(stat="identity") + scale_x_date(labels = scales::date_format("%d-%b"), date_breaks = "3 day")
I expected the bars to appear only above the day in which they are stored in the dataframe and not as it is shown in the chart, i.e. $29.2 above 31st May 2019 only and not spreading from 23rd May to 8th June; same for the second data point. Can anyone advise how I may correct this in my code?
Thanks in advance for any help, I've tried looking all over for a solution.