rggplot2

Setting limits for x axis and y axis for Q-Q plot


I have below Q-Q plot

library(ggplot2)
ggplot(data.frame('Val' = 
c(-0.6434733395, -0.0000935279, -1.2176148541, -0.4817091973, 1.1364799871, -0.8810002309, -0.8383323744, -0.7285213185, 1.6299068100, 1.0358721646, -1.5631088786, -0.6265271885,-1.1331727142, -0.7129360871,
1.6266852445, -0.3328868518, -0.9638501136, 0.1088177257, -0.6034307366, -0.3342069674, 0.0932110885, 0.1088177257, 1.9742990366, 0.6584310789, 0.7201386429, 0.9314809258, 1.1455416757)), aes(sample = Val)) + 
stat_qq() + stat_qq_line() + scale_x_continuous(limits = c(-3, 3)) + scale_y_continuous(limits = c(-3, 3))

Here I have put the limits of x axis and y axis as c(-3, 3) manually. If I had put c(-2, 2), since with c(-3, 3) Q-Q plot does not occupy entire plot window, then the diagonal line would not be visible.

So I wonder if there is any way to put such limit (symmetric) programmatically, solely based on the data, so that my plot would occupy entire plot window irrespective of the data and still see the diagonal line drawn properly?


Solution

  • yes! You can calculate both theoretical and actual quantiles using qqnorm() and then find the maximum absolute value among all quantiles. Round it up and then use it as use this value symmetrically for both axes:

    library(ggplot2)
    
    # your data
    data <- data.frame('Val' = c(-0.6434733395, -0.0000935279, -1.2176148541, -0.4817091973, 
                                 1.1364799871, -0.8810002309, -0.8383323744, -0.7285213185, 
                                 1.6299068100, 1.0358721646, -1.5631088786, -0.6265271885,
                                 -1.1331727142, -0.7129360871, 1.6266852445, -0.3328868518, 
                                 -0.9638501136, 0.1088177257, -0.6034307366, -0.3342069674, 
                                 0.0932110885, 0.1088177257, 1.9742990366, 0.6584310789, 
                                 0.7201386429, 0.9314809258, 1.1455416757))
    
    
    theoretical_q <- qqnorm(data$Val, plot.it = FALSE)$x # Calculate theoretical quantiles for the data
    
    actual_q <- qqnorm(data$Val, plot.it = FALSE)$y # Get actual data quantiles
    
    
    max_abs_value <- max(abs(c(theoretical_q, actual_q))) # Find the maximum absolute value among both theoretical and actual quantiles
    # Round up to the next 0.5 to get a nice limit
    limit <- ceiling(max_abs_value * 2) / 2
    
    # plot with calculated symmetric limits
    ggplot(data, aes(sample = Val)) + 
      stat_qq() + 
      stat_qq_line() + 
      scale_x_continuous(limits = c(-limit, limit)) + 
      scale_y_continuous(limits = c(-limit, limit))
    

    Out: out

    Or just leave the scaling away entirely:

    ggplot(data, aes(sample = Val)) + 
      stat_qq() + 
      stat_qq_line() 
    

    without scale