12

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

enter image description here enter image description here

OS: Debian 9
R: 3.4.0

Léo Léopold Hertz 준영
  • 134,464
  • 179
  • 445
  • 697
  • 1
    Try `scale_x_continuous(breaks=pretty(rev(Vars), length(Vars)/2))` – juan Jul 17 '17 at 15:52
  • @juan I get `Error in rev(Vars) : object 'Vars' not found` with your proposal. – Léo Léopold Hertz 준영 Jul 17 '17 at 16:27
  • 1
    Sorry about that! This won't work for dates unless you pass `as.Date`, which is overly complicated. @EricWatt's answer is what you should use. – juan Jul 17 '17 at 16:40
  • 1
    per linked answer, it works if you call `as.numeric`, eg, `ggplot(data=my.data, aes(as.numeric(date), vals)) + geom_line() + scale_x_continuous(breaks=pretty(as.numeric(rev(my.data$date))))`, but then you probably want to add labels, and I find this is overly complicated! – juan Jul 17 '17 at 17:03
  • 1
    Sorry, you need to specify the number of breaks in `pretty`, so add `pretty(..., n=4)`. – juan Jul 17 '17 at 19:00
  • @juan Please, see the body for the output. What do you think? – Léo Léopold Hertz 준영 Jul 17 '17 at 19:21
  • I couldn't reproduce your error. Copied your code and [it works for me](http://imgur.com/a/6EE3O). – juan Jul 17 '17 at 19:30
  • 1
    [Here it is](http://imgur.com/a/iZlNv) with labels: `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=4), labels=format(rev(my.data$date), format="%m/%d/%y"))` – juan Jul 17 '17 at 19:33

2 Answers2

7

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.

Eric Watt
  • 3,180
  • 9
  • 21
  • It has a tick mark and label for dates 1, 3, and 5, skipping 2 and 4. Is there something else you expected? – Eric Watt Jul 17 '17 at 16:31
  • 1
    Your dates are `c("2011-07-22","2011-07-23", "2011-07-24","2011-07-28","2011-07-29")`. The dates for #2 and #4 are `"2011-07-23"` and `"2011-07-28"`. These are the dates you want to skip labels on the x axis. The dates you want shown are `"2011-07-22"`, `"2011-07-24"`, and `"2011-07-29"`. The output in the image you provided based on my code shows exactly these dates. I'm not understanding what output you would like, but this provides exactly what you've described in the question. – Eric Watt Jul 17 '17 at 19:05
  • 1
    I used `scale_x_date` not `scale_x_discrete`. Also try leaving off the `labels` parameter. – Eric Watt Jul 17 '17 at 19:43
  • I can't test your Actual Code because I don't have `molten` data. If the reproducible example doesn't demonstrate the problem you're having, it's not a good reproducible example. Maybe modify the simplified example so that it represents what you're trying to do? – Eric Watt Jul 18 '17 at 14:43
  • I found a solution based on the other thread actual data and your answer. I added it here as a wiki answer. – Léo Léopold Hertz 준영 Jul 18 '17 at 15:14
4

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")
Léo Léopold Hertz 준영
  • 134,464
  • 179
  • 445
  • 697
  • 1
    I like this answer better because 'date_breaks' gives an easier way to manipulate the date interval and including 'date_labels' was very useful with the formatting. – Ricecakes Nov 14 '18 at 00:16