2

I am having some issues using the scatter3d function, specifically that it seems to be impossible to dictate to the function what the limits of the axis should be. Here's my basic plotting function with a few datapoints from the set I'm working with:

library(rgl)
library(plot3D)
library(car) 

df <- data.frame(meanX = c(147.34694, 173.89244, 135.73004, 121.93766,
                           109.72152,  92.53709, 165.46588, 169.77744,
                           127.01796,  99.34347),
                 meanY = c(140.40816, 110.99128, 134.56023, 164.18703,
                           166.04051, 155.97329, 105.29377, 104.42683,
                           130.17066, 155.99696),
                 avgDist = c(40.788118, 12.957329, 14.24348, 39.10424,
                             34.694258, 25.532335, 21.491695,23.528944,
                             9.309201,  31.916879))

car::scatter3d(x = df$meanX, y = df$meanY, z = df$avgDist, surface = FALSE)

This plots fine, but sets up default axis ranges of

xlim = c(90,200) 
ylim = c(100,200)
zlim = c(9,40)

The problem is, thatIi seem to be completely unable to change this. I know that RGL does not allow clipping, and I don't want it to exclude any data points here, but the axis range is quite a bit higher than the maximum value of each axis

max(df$meanX)
[1] 173.8924

max(df$meanY)
[1] 166.0405

max(df$avgDist)
[1] 40.78812

What I'd like to do, is to set the axis limit on both X and Y from 70 to 185, from what I can tell, this SHOULD be possible with this code:

car::scatter3d(x = df$meanX, y = df$meanY, z = df$avgDist, surface = FALSE,
          xlim = c(70,185), ylim = c(70,185))

But this just produces the same plot (with no errors or warnings). Anyone know how to manually set these axis?

Vincent Bonhomme
  • 7,235
  • 2
  • 27
  • 38
  • You should not be loading plot3D; it's not related to either rgl or scatter3d. – IRTFM May 25 '16 at 19:24
  • rgl *does* allow clipping. I don't know about scatter3d, but plot3d would do it for you: plot3d(x = df$meanX, y = df$meanY, z = df$avgDist, xlim = c(70,185), ylim = c(70,185)) – user2554330 May 25 '16 at 20:11
  • Hmm right you are, guess it's just the {car} package that has issues with the limits, now i just have issues getting the surface3d function i had just gotten working yesterday to work with plot3d as well :) – Kári Gunnarsson May 25 '16 at 22:08

1 Answers1

1

In situations where axis.scales = TRUE, now the default, the code to set the min and max labels and ticks for each axis is chosen by the non-exported car:::nice function. You can call with axis.scales=FALSE and then redo the work of adding axis ticks and labels.

with( df,  scatter3d( meanX , meanY, avgDist, axis.scales = FALSE, 
           xlim = c(70,185), ylim = c(70,185), zlim = c(9,40) ))

Alternatively you could try to rewrite the code to check to see if any of the xlim, ylim, or zlim parameters are present and substitute those values for the ones set up by this bit of code in car:::scatter3d:

car:::scatter3d
#------- code near the top of the console display------
if (axis.scales) {
    lab.min.x <- nice(minx)
    lab.max.x <- nice(maxx)
    lab.min.y <- nice(miny)
    lab.max.y <- nice(maxy)
    lab.min.z <- nice(minz)
    lab.max.z <- nice(maxz)
    minx <- min(lab.min.x, minx)
    maxx <- max(lab.max.x, maxx)
    miny <- min(lab.min.y, miny)
    maxy <- max(lab.max.y, maxy)
    minz <- min(lab.min.z, minz)
    maxz <- max(lab.max.z, maxz)
    min.x <- (lab.min.x - minx)/(maxx - minx)
    max.x <- (lab.max.x - minx)/(maxx - minx)
    min.y <- (lab.min.y - miny)/(maxy - miny)
    max.y <- (lab.max.y - miny)/(maxy - miny)
    min.z <- (lab.min.z - minz)/(maxz - minz)
    max.z <- (lab.max.z - minz)/(maxz - minz)
}

I thought it would be would be OK to allow the lim values to modify only when they were on the interior of the nice values, but this code errors out, so will need logic to detect missing-ness of the lims:

    lab.min.x <- max( nice(minx), xlim[1])
    lab.max.x <- min( nice(maxx), xlim[2])
    lab.min.y <- max( nice(miny), ylim[1])
    lab.max.y <- min( nice(maxy), ylim[2])
    lab.min.z <- max( nice(minz), zlim[1])
    lab.max.z <- min( nice(maxz), zlim[2])
IRTFM
  • 258,963
  • 21
  • 364
  • 487