0

I am trying to plot a scatterplot in shiny, using times of day on the y axis. When plotting multiple points, the y axis looks great.

sample plot

Here's the code:

     output$outputPlot <- renderPlot({
        coords <- subset(coords, location == input$cities)
        month <- coords$month
        time <- strptime(coords$format_time, format = "%l:%M:%S %p")
        plot(month, time)
      })

But when there's only 1 data point in coords, the plot's time scale on the y-axis isn't in terms of time anymore, and the data point appears in the middle of the graph.

sample plot 2

Thanks for your help!

r2evans
  • 141,215
  • 6
  • 77
  • 149
  • 1
    Welcome to Stack Overflow. Read and include features from [How to make a great R reproducible example](https://stackoverflow.com/questions/5963269), especially the part about reproducing and pasting your data. The dataset is not available for us to demonstrate with; think of using a smaller example that can be included in your question. For example, does the problem occur with just a normal (non-Shiny) graph? If so, present that simplified example instead. – wibeasley May 31 '19 at 19:32

1 Answers1

1

What you're seeing is that R doesn't know how to guess an appropriate range for a single point. Typically it expands the range of data by 4% of the range (look at ?par and look for 'xaxs'), but with a single point that means nothing.

So we need to tell it what ylim to use. (Similarly, your x-axis needs some guidance, too.)

Fake data:

set.seed(2)
coords <- data.frame(tm = Sys.time() + runif(20, -3e7, 3e7))
coords$month <- as.integer(format(coords$tm, format = "%m"))
coords$format_time <- format(coords$tm, format = "%l:%M:%S %p")
head(coords)
#                    tm month format_time
# 1 2018-10-24 20:15:17    10  8:15:17 PM
# 2 2019-10-19 05:07:04    10  5:07:04 AM
# 3 2019-07-21 14:19:22     7  2:19:22 PM
# 4 2018-10-13 03:44:57    10  3:44:57 AM
# 5 2020-04-03 21:32:22     4  9:32:22 PM
# 6 2020-04-03 15:27:59     4  3:27:59 PM

The "normal" plot looks fine:

month <- coords$month
time <- strptime(coords$format_time, format = "%l:%M:%S %p")
plot(month, time)

many points, good y-axis

but the single-point does not:

sub <- coords[1,]
month <- sub$month
time <- strptime(sub$format_time, format = "%l:%M:%S %p")
plot(month, time)

single point, wrong y-axis

So we fix it by specifying the xlim and ylim arguments. In this case, since I'm inferring it is meant to be a year of months (x) and a day of times (y), I can hard-code them, but in other situations you might want to just substract/add a small amount from the one datum you have:

sub <- coords[1,]
month <- sub$month
time <- strptime(sub$format_time, format = "%l:%M:%S %p")
xlim <- c(1, 12)
ylim <- strptime(c("12:00:00 AM", "11:59:59 PM"), format = "%l:%M:%S %p")
plot(month, time, xlim = xlim, ylim = as.numeric(ylim))

one point, corrected axes

You only need to specify ylim to answer this question, but without setting xlim= here, the previous x-axis spanned 6-14, not good for months. Also of note is that I had to coerce ylim to numeric for the plot, it did not work with ylim in its pure POSIXt form ... not sure exactly why that is the case, but this doesn't detract from the utility of the plot in general.

r2evans
  • 141,215
  • 6
  • 77
  • 149