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$
  • $\begingroup$ Have you tried wrapping the whole ListPointPlot3D with Dynamic instead of pointsDgd3DOpt[[1 ;; nEndpoint]]? $\endgroup$ – Sascha Jul 11 '16 at 6:22
  • $\begingroup$ That throws "Could not combine the graphics objects in Show[...]" $\endgroup$ – Basti Jul 11 '16 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 Jul 11 '16 at 6:46
  • $\begingroup$ Sure, I've edited one in. $\endgroup$ – Basti Jul 11 '16 at 7:00
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$
  • $\begingroup$ This is simple and works perfect, thanks! $\endgroup$ – Basti Jul 11 '16 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$
  • 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 Jul 11 '16 at 8:43
  • $\begingroup$ As a workaround, amend Slider in a following way Slider[Dynamic@uLimit, {1, 300, 1}, ContinuousAction -> False] $\endgroup$ – e.doroskevic Jul 11 '16 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 Jul 11 '16 at 8:59

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.