15
$\begingroup$

I have several sigmoidal fits to 3 different datasets, with mean fit predictions plus the 95% confidence limits (not symmetrical around the mean) and the actual data.

I would now like to show these different 2D plots projected in 3D as in enter image description here

but then using proper perspective.

In the link here they give some solutions to combine the plots using isometric perspective, but I would like to use proper 3 point perspective. Any thoughts? Also any way to show the mean points per time point for each series plus or minus the standard error on the mean would be cool too, either using points+vertical bars, or using spheres plus tubes.

Below are some test data and the fit function I am using. Note that I am working on a logit(proportion) scale and that the final vertical scale is Log10(percentage).

(* some test data *)
data = Table[Null, {i, 4}];
data[[1]] = {{1, -5.8}, {2, -5.4}, {3, -0.8}, {4, -0.2}, {5, 
   4.6}, {1, -6.4}, {2, -5.6}, {3, -0.7}, {4, 0.04}, {5, 
   1.0}, {1, -6.8}, {2, -4.7}, {3, -1.0}, {4, 0.03}, {5, 
   2.8}};  (* data on logit(proportion) scale *)
data[[2]] = ((data[[1]] // Transpose))*{1, 0.8} // Transpose; 
data[[3]] = ((data[[1]] // Transpose))*{1, 0.6} // Transpose; 
data[[4]] = ((data[[1]] // Transpose))*{1, 0.4} // 
  Transpose; (* data points groups 1-4 on logit(proportion) scale *)
Logit[p_] = Log[p/(1 - p)];
Invlogit[x_] = Exp[x]/(1 + Exp[x]);
datalog = Table[Null, {i, 4}];
Do[datalog[[i]] = 
   Partition[
    Riffle[(data[[i]] // Transpose)[[1]], 
     Log10[100*Invlogit[(data[[i]] // Transpose)[[2]]]]], 2], {i, 1, 
   4}];

(* fit function plus best fit & conf lims *)
fitfunc[t_, z_, Z_, p0_, s_] := 
  z + (p0 (z - Z))/(-p0 + (-1 + p0) (1/(1 + s))^t);
predicted = 
  Table[NonlinearModelFit[
    dat[[i]], {fitfunc[t, z, Z, p0, s]}, {{Z, 0.46}, {s, 20}, {p0, 
      0.0005}, {z, -6.4}}, t, MaxIterations -> 1000, 
    Method -> "LevenbergMarquardt"], {i, 4}];
pred[t_, i_] := Normal[predicted[[i]]];
conflims[t_, i_] := predicted[[i]]["MeanPredictionBands"];
$\endgroup$
  • 3
    $\begingroup$ This is likely doable. However, I'm sure this is also one of the things that would give Tufte quite a fit; you could do just as well with all three ribbon plots in two dimensions, perhaps in separate plots if combining them proves interfering. $\endgroup$ – J. M. is away Jun 11 '15 at 21:41
  • $\begingroup$ Well I tried multipanel plots before - it's just that in the article where I would like to use this I will not have the space to do this (I have 5 groups, which would be 5 panels, and the curves and points also overlap too much to be able to overlay them in one 2D graph, even when using transparency). So the 3D way that I show would be the only way to combine everything within the space that I have. $\endgroup$ – Tom Wenseleers Jun 12 '15 at 5:12
  • 1
    $\begingroup$ And to be able to read the Y values more clearly I would still like to add Y grid lines at the back and maybe invert the X scale so that the high Y values would be at the back (it's only the values at the endpoint that matter really for me). $\endgroup$ – Tom Wenseleers Jun 12 '15 at 9:02
  • $\begingroup$ Instead of assembling 2d to 3d, one can fit directly to 3d with a curvature in third axis direction. $\endgroup$ – Narasimham Jun 14 '15 at 4:53
  • 1
    $\begingroup$ Ha no but the different groups are not logically ordered, so it wouldn't make sense to also do a fit in the 3d axis direction - it's separate categorical groups really that I want to show next to each other $\endgroup$ – Tom Wenseleers Jun 14 '15 at 7:16
19
+100
$\begingroup$

You could make 2d plot and then convert 2d coord to 3d:

data1 = {{1, -5.8}, {2, -5.4}, {3, -0.8}, {4, -0.2}, {5, 
    4.6}, {1, -6.4}, {2, -5.6}, {3, -0.7}, {4, 0.04}, {5, 
    1.0}, {1, -6.8}, {2, -4.7}, {3, -1.0}, {4, 0.03}, {5, 2.8}};

data = Table[{1, 1.2 - j*.2} i, {j, 4}, {i, data1}];

Logit[p_] = Log[p/(1 - p)];
Invlogit[x_] = Exp[x]/(1 + Exp[x]);
datalog = Table[Null, {i, 4}];

datalog = 
  Table[Transpose[{#1, Log10[100 Invlogit[#2]]} & @@ 
     Transpose[data[[i]]]], {i, 1, 4}];

fitfunc[t_, z_, Z_, p0_, s_] := 
  z + (p0 (z - Z))/(-p0 + (-1 + p0) (1/(1 + s))^t);

predicted = 
  Table[NonlinearModelFit[
    data[[i]], {fitfunc[t, z, Z, p0, s], 
     Z > z && Z < 5 && s > 1 && s < 200 && p0 < 0.01 && p0 > 0 && 
      z < -2 && z > -7}, {{Z, 0.3}, {s, 20}, {p0, 0.001}, {z, -6.5}}, 
    t, MaxIterations -> 1000], {i, 4}];

pred[t_, i_] := Normal[predicted[[i]]];
conflims[t_, i_] := predicted[[i]]["MeanPredictionBands"];

cols = {Red, Darker[Green], Blue, Darker[Cyan]};

opac = 0.4;
colslight = {Directive[cols[[1]], Opacity[opac]], 
   Directive[cols[[2]], Opacity[opac]], 
   Directive[cols[[3]], Opacity[opac]], 
   Directive[cols[[4]], Opacity[opac]]};

Graphics3D[
 Table[{Plot[{Log10[100*Invlogit[pred[t, i]]], 
       Evaluate[N@Log10[100*Invlogit[conflims[t, i]]]]}, {t, 1, 5}, 
      Filling -> {2 -> {{1}, {colslight[[i]]}}, 
        3 -> {{1}, {colslight[[i]]}}}, 
      PlotStyle -> {cols[[i]], colslight[[i]], 
        colslight[[i]]}][[1]], {cols[[i]], PointSize[0.012], 
     Point[datalog[[i]]]}} /. {x_?NumericQ, y_?NumericQ} :> {x, i, 
     y}, {i, 1, 4}], 
    Axes -> {True, False, True}, 
    Boxed -> {Right, Bottom, Back}, 
    BoxRatios -> {1, 1, 0.5}, 
    FaceGrids -> {{0, 0, -1}, {0, 1, 0}, {1, 0, 0}}, 
    FaceGridsStyle -> 
  Directive[GrayLevel[0.3, 1], AbsoluteDashing[{1, 2}]],
 ViewPoint -> {-2, -2.5, 1}, 
 AxesLabel -> {"Day", "", 
   Rotate[Row[{Spacer[50], "Resistance (%)"}], 90 Degree]},
 LabelStyle -> Directive[Black, Bold, 14],
 ImageSize -> 500
   ]

enter image description here

$\endgroup$
  • $\begingroup$ Many thanks for this! Brilliant! And how would you change the points to means and 95% conf lims? $\endgroup$ – Tom Wenseleers Jun 14 '15 at 6:28
  • $\begingroup$ also one other question: if I wanted to represent the points using sphereas and the 95% conf lims using tubes - would you know how to do that? Replacing Point with Sphere[datlog[[i]], 0.07] gets close for the first part - but the aspect ratio of the balls is incorrect then... $\endgroup$ – Tom Wenseleers Jun 15 '15 at 8:55
  • $\begingroup$ Or would using Circulsphere[] work to get the aspect ratio right? $\endgroup$ – Tom Wenseleers Jun 15 '15 at 10:29
  • $\begingroup$ or you could set BoxRatios -> {1, 1, 1} if you don't mind $\endgroup$ – halmir Jun 15 '15 at 13:34
  • $\begingroup$ Yes that's true, but I kind of liked the current aspect ratio. Maybe with some code given at mathematica.stackexchange.com/questions/10999/… I could get it to work.... $\endgroup$ – Tom Wenseleers Jun 15 '15 at 15:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.