Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

While trying to analyse several different datasets I got what I thought was a good idea: define a "function" that returns a Manipulate object. But this has some problems when larger amounts of data are passed to Manipulate. When the code is first run there is long delay before the manipulate pane is displayed, because the the data gets embedded inside "Body" of Manipulate.

Here is a code snippet that illustrates the problem:

(*Generate some data*)
data = RandomVariate[BinormalDistribution[Abs@Random[]], {5, 10^4}];
histograms = DensityHistogram[#, 30, PerformanceGoal -> "Speed"] & /@ data;
images = Rasterize[#, ImageSize -> Medium] & /@ histograms;

AnalysePlots[plots_] := 
  Manipulate[plots[[i]], {i, 1, Length[plots], 1}];

(*Now compare:*)
t = AbsoluteTime[];
AnalysePlots[images] // AbsoluteTiming
AbsoluteTime[] - t
(* ==>3.7091792<---HERE IMAGES GET EMBEDDED*)

t = AbsoluteTime[];
Manipulate[images[[i]], {i, 1, Length[images], 1}] // AbsoluteTiming
AbsoluteTime[] - t

(* ==>0.0312500<---Here they don't*)

Can I somehow choose whether to embed the data (in this case the variable plots) into Manipulate?

When developing the function AnalysePlots it would be nice if I could do something like:

AnalysePlots[images, "Embed"->False]

which would have the benefit of displaying quickly. Then when I've finished AnalyzePlots I would deploy it with:

AnalysePlots[images, "Embed"->True]

which I could then copy and paste to a new notebook, deploy to CDF etc...

(I've already tried SaveDefinitions->False and UnsavedVariables :> {plots})

share|improve this question
    
It is something to do with defining your Manipulates via functions. Because this starts very quickly: Manipulate[rasterizedSmall[[i]], {i, 1, Length[rasterizedSmall], 1}] –  Vitaliy Kaurov May 23 '12 at 22:46
add comment

2 Answers 2

up vote 2 down vote accepted

This should do the trick:

SetAttributes[AnalysePlots, HoldFirst]

and if you want to embed the images use Evaluate:

AnalysePlots[Evaluate@images]
share|improve this answer
    
+1 This indeed works. Could you comment on why it works? –  Ajasja May 24 '12 at 12:43
    
@Ajasja, without setting HoldFirst the symbol images gets evaluated by AnalysePlots, so the call to Manipulate is Manipulate[(**HUGE CHUNK OF DATA**)[[i]],.... Setting the HoldFirst attribute tells AnalysePlots to pass images[[i]] through to Manipulate unevaluated, so the call to Manipulate is Manipulate[images[[i]],..., just as it is when you call Manipulate directly in your second example. –  Simon Woods May 24 '12 at 14:06
add comment

During lunch I had an inspiration: If SaveDefinitions-> False is not working on named argument patters of SetDelayed (probably due to special scoping), then perhaps it will work on variables defined using Module. So the following works OK:

Options[AnalysePlots] = Options[Manipulate];
AnalysePlots[plots_, opts : OptionsPattern[]] := 
 Module[{aplots = plots},
  Manipulate[aplots[[i]], {i, 1, Length[aplots], 1}, opts]]

(*Now compare:*)
t = AbsoluteTime[];
AnalysePlots[images, SaveDefinitions -> False] // AbsoluteTiming
AbsoluteTime[] - t
(* ==>0.025<---no images embedded*)

t = AbsoluteTime[];
Manipulate[images[[i]], {i, 1, Length[images], 1}] // AbsoluteTiming
AbsoluteTime[] - t

(* ==>0.39<---no images embedded*)

t = AbsoluteTime[];
AnalysePlots[images, SaveDefinitions -> True] // AbsoluteTiming
AbsoluteTime[] - t
(* ==>7.045<---HERE IMAGES GET EMBEDDED*)
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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