2
$\begingroup$

I have a graphic that consists of a ListPlot3D and a ListPointPlot3D. I want to only display part of the data for the second plot up to an nth index. That data is in pointsDgd3DOpt, so I select with pointsDgd3DOpt[[;; nEndpoint]]. That variable is in manipulate. But the first plot is slow and should not be updated when that variable changes. I've read in the "Advanced Manipulate Functionality" article how to do that in general (an inner dynamic). But that doesn't really work for me.

Without dynamic, it works but is slow:

pointsDgd3D = 
  Import[FileNameJoin[{NotebookDirectory[], 
     "filter_small_space.txt"}], "CSV"];
pointsDgd3DOpt = 
  Import[FileNameJoin[{NotebookDirectory[], 
     "filter_small_space_opt.txt"}], "CSV"];
func = Interpolation[pointsDgd3D];

Manipulate[
 Show[{
   ListPlot3D[pointsDgd3D,
    PlotRange -> Dynamic[{0, 3}]
    ],
   ListPointPlot3D[
    pointsDgd3DOpt[[;; nEndpoint]],
    PlotRange -> {0, 3}
    ]
   }],
 {nEndpoint, 1, 300, 1}
 ]

And with it spews "must be a valid array or a list of valid arrays" errors:

Manipulate[
 Show[{
   ListPlot3D[pointsDgd3D,
    PlotRange -> {0, 3}
    ],
   ListPointPlot3D[
    Dynamic[pointsDgd3DOpt[[1 ;; nEndpoint]]],
    PlotRange -> {0, 3}
    ]
   }],
 {nEndpoint, 3, 300, 1}
 ]

Any pointers to what's happening?

EDIT: MWE:

pointsDgd3D = 
  Flatten[Table[{x, y, x*x + y*y}, {x, 0, 2, 0.2}, {y, 0, 2, 0.2}], 1];
pointsDgd3DOpt = RandomChoice[pointsDgd3D, 100];
func = Interpolation[pointsDgd3D];
Manipulate[
 Show[{
   ListPlot3D[pointsDgd3D],
   ListPointPlot3D[
    pointsDgd3DOpt[[1 ;; nEndpoint]],
    PlotStyle -> {Green, PointSize[0.1]}
    ]
   }],
 {nEndpoint, 3, 100, 1}
 ]
$\endgroup$
4
  • $\begingroup$ Have you tried wrapping the whole ListPointPlot3D with Dynamic instead of pointsDgd3DOpt[[1 ;; nEndpoint]]? $\endgroup$
    – Sascha
    Commented Jul 11, 2016 at 6:22
  • $\begingroup$ That throws "Could not combine the graphics objects in Show[...]" $\endgroup$
    – Basti
    Commented Jul 11, 2016 at 6:28
  • $\begingroup$ If you can post a MWE that one can run,someone can show you now to do it. Your example is not possible to use, since you have Import[FileNameJoin[{NotebookDirectory[], "filter_small_space.txt"}], "CSV"] which uses your own local files. $\endgroup$
    – Nasser
    Commented Jul 11, 2016 at 6:46
  • $\begingroup$ Sure, I've edited one in. $\endgroup$
    – Basti
    Commented Jul 11, 2016 at 7:00

3 Answers 3

3
$\begingroup$

Here is the "nested Dynamic" approach the tutorial suggests.

Dynamic Points special case

You can't just put Dynamic in the ListPointPlot3D but you can in Graphics3D.

Manipulate[Show[{
   Plot3D[func[x, y], {x, 0, 2}, {y, 0, 2}, PlotPoints -> 50],
   Graphics3D[
    {Green, PointSize[0.1], 
     Dynamic@Point[pointsDgd3DOpt[[1 ;; nEndpoint]]]}
    ]
   }], {nEndpoint, 3, 100, 1}]

General nested Dynamics in 3D graphics

For more complicated, than a list of points, cases you can't put e.g Dynamic@Plot3D[... in Show but you can put Graphics3D[{Dynamic@First@Plot3D[...]}].

$\endgroup$
1
  • $\begingroup$ This is simple and works perfect, thanks! $\endgroup$
    – Basti
    Commented Jul 11, 2016 at 8:54
3
$\begingroup$

I use the tick method for all my demos and Manipulate. It works all the time and for all problems. It is based on the event callback method used in standard GUI frameworks. An event happens (such as moving a slider, or clicking a button) then a local action is performed, only based on that one event. Then the GUI is updated. This means no other action needs to be done.

In this method, there is only one dynamic for the whole Manipulate that is tracked. So it is also very fast. When you want to update the main GUI (Manipulate expression), just tickle this one dynamic variable(the tick). It is boolean. So to tickle just flip it. In this method, you need to initialize all the dynamics you are using. Most can be done using {{a,initalValue},None} syntax.

Here is for your MWE

pointsDgd3D = 
  Flatten[Table[{x, y, x*x + y*y}, {x, 0, 2, 0.2}, {y, 0, 2, 0.2}], 1];
pointsDgd3DOpt = RandomChoice[pointsDgd3D, 100];
func = Interpolation[pointsDgd3D];

Manipulate[
 tick; (*must be here, so it is tracked*)

 Show[{p2, p1}],

 (*controls*)
 Grid[{{Manipulator[Dynamic[nEndpoint,
      {tick = Not[tick]; (*flip to update main GUI*)
        p1 = ListPointPlot3D[ (*update only this one plot*)
          pointsDgd3DOpt[[1 ;; nEndpoint]],
          PlotStyle -> {Green, PointSize[0.1]}];
        nEndpoint = #} &], {3, 100, 1}, ImageSize -> Tiny], 
    Dynamic[nEndpoint]}}],

 (*local dynamics below*)
 {{nEndpoint, 3}, None},
 {{p1, {}}, None},
 {{p2, ListPlot3D[pointsDgd3D]}, None}, (*second plot not affected*)
 {{tick, False}, None},

 TrackedSymbols :> {tick} (*tack only the tick*)
 ]

animation

ps. There are other ways to handle the problem at hand, but I use this method since it is simple and works for everything.

$\endgroup$
2
$\begingroup$

Here is an example with DynamicModule

Example

DynamicModule[
 {data, sample, uLimit},

 data = RandomReal[{-5, 5}, {1000, 3}];
 sample = RandomSample[data, 300];
 uLimit = 100;

 Column[{
   Slider[Dynamic@uLimit, {1, 300, 1}, ContinuousAction -> False],
   Dynamic @ Show[{
      ListPlot3D @ data,
      ListPointPlot3D[
       sample[[;; uLimit]],
       PlotStyle -> Directive[Red, PointSize @ 0.05]
       ]
      },
     Boxed -> False]
   },
  Alignment -> Center]
 ]

Output

output

$\endgroup$
3
  • 1
    $\begingroup$ This exhibits exactly the behavior I want to prevent: While moving the slider, the ListPlot gets undetailed. I assume that's because it's being reevaluated. I want the Plot to stay the same during slider changes. $\endgroup$
    – Basti
    Commented Jul 11, 2016 at 8:43
  • $\begingroup$ As a workaround, amend Slider in a following way Slider[Dynamic@uLimit, {1, 300, 1}, ContinuousAction -> False] $\endgroup$ Commented Jul 11, 2016 at 8:56
  • $\begingroup$ But I DO want to have continuous action :D. The context is that this will be used in a presentation. The Plot is slow and I want to show the progress of the points on the surface (they're points of evaluation of an algorithm). There is a good solution here now though. Thanks anyways! $\endgroup$
    – Basti
    Commented Jul 11, 2016 at 8:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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