2

I've got a simple plot with the year on the x axis and population on the y axis. Why does the year have decimal at the end of it? I'm not sure how to format this. It's a numeric in a data frame.

dput(head(that[,c("year","pop")]))

structure(list(year = c(2010, 2011, 2012, 2013, 2014, 2015), 
pop = c(9574323, 9657592, 9749476, 9843336, 9932887, 10031646
)), row.names = c("1", "2", "3", "4", "5", "6"), class = "data.frame")

ggplot(that, aes(year, pop)) +
  geom_point() +
  geom_smooth(method = "lm", se = FALSE )

**Plot**

r2evans
  • 141,215
  • 6
  • 77
  • 149
DaCrDg
  • 25
  • 3
  • 1
    Welcome to SO, DaCrDg! Up front, *we have no idea*, because we don't have your data. Please make this question *reproducible*. This includes sample code (including listing non-base R packages), sample *unambiguous* data (e.g., `dput(head(x))` or `data.frame(x=...,y=...)`), and expected output. Refs: https://stackoverflow.com/questions/5963269, [mcve], and https://stackoverflow.com/tags/r/info. – r2evans Mar 25 '20 at 15:44
  • If it's `numeric`, then you can use `scale_x_continuous` to control aspects of the axis such as where the ticks/`breaks=` occur and how they look (`labels=`). Since it's year, is there a reason you are not using `Date` class objects? In that case, it would be `scale_x_date(..., breaks=, labels=)` – r2evans Mar 25 '20 at 15:59
  • Sorry, I'm pretty new to this. I'm not exactly sure how to show it, but I have a data frame with years in the first column. I made those a numeric class, but it seems I need to make them a date class. – DaCrDg Mar 25 '20 at 16:15
  • Read the links, really, please. The first one specifically mentions (as I did) doing `dput(head(x))` where `x` is your frame. – r2evans Mar 25 '20 at 16:19
  • dput(head(that$year)) c(2010, 2011, 2012, 2013, 2014, 2015) – DaCrDg Mar 25 '20 at 16:21
  • ggplot(that, aes(year, pop))+ + geom_point()+ + geom_smooth(method = "lm", se = FALSE – DaCrDg Mar 25 '20 at 16:27
  • (1) Please [edit] your question and put all relevant data and code there. Comments can easily be missed by readers or hidden by the interface. (2) If you want somebody to be able to test-plot your data, we need more than just `year`, perhaps `dput(head(that[,c("year","pop")]))` if you want to limit it to just those two columns. (3) In general, we are all volunteering our time, your job is to [research first](https://meta.stackoverflow.com/q/261592) then make it as easy for us as you can; the better you ask, the more likely somebody can answer. Quickly. – r2evans Mar 25 '20 at 16:33
  • I don't mean to be difficult. I appreciate the help – DaCrDg Mar 25 '20 at 16:52

1 Answers1

2

You can control the axis breaks (and labels) with scale_x_continuous. Try this:

ggplot(that, aes(year, pop)) +
  geom_point() +
  geom_smooth(method = "lm", se = FALSE) +
  scale_x_continuous(breaks = seq(ceiling(min(that$year)), floor(max(that$year)), by = 2))

I use ceiling and floor to round the numbers, and to push them "inward" on the plot (if fractional). by=2 is arbitrary, it depends on your data. If you need this to be dynamic (various ranges), then seq(from, to, length.out=) makes sense, but it can lead to fractional years, so you need to do some "math" and logic to determine a reasonable by= instead, such as

diff(range(that$year))
# [1] 5
diff(range(that$year)) / 4
# [1] 1.25

yearby <- round(diff(range(that$year)) / 4) # assuming you want "4"-ish ticks, more or less
ggplot(that, aes(year, pop)) +
  geom_point() +
  geom_smooth(method = "lm", se = FALSE) +
  scale_x_continuous(breaks = seq(ceiling(min(that$year)), floor(max(that$year)), by = yearby))
r2evans
  • 141,215
  • 6
  • 77
  • 149
  • That worked, thank you very much. If I made the dates column in the data frame as dates, instead of numeric, would this make it to where I wouldn't have to do the scale_x_continous part? – DaCrDg Mar 25 '20 at 17:15
  • If you converted to `Date`, you may not need `scale_x_date`, but you should not use `scale_x_continuous` (since it is a different class). If all of your data are integer years, though, I don't see a need at this point to change that, I'd stick with `numeric` (or `integer`). – r2evans Mar 25 '20 at 17:30