2

If I have a data.frame df

library(lubridate) library(ggplot2) library(dplyr) day.start = today() df = data.frame(date = seq.Date(from = today() - days(10), to = today() + days(10), 'day')) df$day.idx = as.numeric(df$date - day.start + 1) df$day.idx = ifelse(df$day.idx < 1, df$day.idx + nrow(df), df$day.idx) df = df %>% arrange(day.idx) df$value = 1:nrow(df) 

I can plot the values vs dates like this

ggplot(df) + geom_line(aes(x = date, y = value)) 

However I want to make an adjustment for a custom year so I want the x axis to start at today's date.

## I want the x axis to start with day.start df = df %>% mutate(date = factor(date, levels = as.character(df$date))) ## how to change x axis to behave like dates again? ggplot(df) + geom_point(aes(x = date, y = value)) + geom_line(aes(x = date, y = value)) ## where is this line? 

So the second plot looks better but how do I format the x-axis to look like (nicely spaced) dates again?

 for

1
  • 2
    the function today() is from the lubridate package, don't forget that for your example. Commented Jul 1, 2019 at 19:32

4 Answers 4

1

With your code as is, I get the following message:

geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

So ggplot doesn't know to "connect the dots", this is why the message mentions adjusting the group aesthetic. To combat this, I assigned 1 to gorup.

ggplot(df, aes(x = date, y = value, group = 1)) + geom_point() + geom_line() 

enter image description here

However, I wouldn't recommend this approach because your dates are then out of order, as can be seen if we adjust your x-axis text:

df %>% ggplot(aes(x = date, y = value, group = 1)) + geom_point() + geom_line() + theme(axis.text.x = element_text(angle = 75, hjust = 1)) 

enter image description here

Edit: I'd recommend keeping your date field as a date, and using filter to keep only the observations you want before piping into ggplot:

df %>% mutate(date = as_date(date)) %>% filter(date >= today()) %>% ggplot(aes(x = date, y = value)) + geom_line() + scale_x_date() 

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

ideally as a Date so I can have custom breaks
I'm interested in the whole field. The filter drops observations.
0

If you want the x-axis to stay in the same order as in your example, and you just want it to be readable, I recommend changing the angle of the text:

ggplot(df) + geom_point(aes(x = date, y = value), group = 1) + geom_line(aes(x = date, y = value), group = 1) + theme(axis.text.x = element_text(angle = 75, hjust = 1)) 

1 Comment

What if you have 100s more points on the x-axis? This only works if you have few.
0

Try:

df[df$date > today(), ] %>% mutate(date = as.Date(date)) %>% ggplot(aes(x = date, y = value)) + geom_line() + geom_point() 

EDIT: An option would be to use filter rather than df[df$date > today(), ](check @OTStats's answer)

Comments

0

Found a solution from this answer: https://stackoverflow.com/a/26611593/5319229

Turns out it has nothing to do with factors.

The bdscale package came in handy.

library(lubridate) library(ggplot2) library(dplyr) day.start = today() df = data.frame(date = seq.Date(from = today() - days(10), to = today() + days(10), 'day')) df$day.idx = as.numeric(df$date - day.start + 1) df$day.idx = ifelse(df$day.idx < 1, df$day.idx + nrow(df), df$day.idx) df = df %>% arrange(day.idx) df$value = 1:nrow(df) ggplot(df) + geom_point(aes(x = date, y = value)) + geom_line(aes(x = date, y = value, group = 1))+ bdscale::scale_x_bd(business.dates = df$date, labels = scales::date_format('%b %d')) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.