I have Manipulate, where there are
FileNameSetter(to load file with data points)InputFieldfor setting a function- "Plot region" to present graph of function and scatter of points .
Firstly I had hardcoded the path to file and function too. So after Evaluate there are correctly drawn graph and scatter. After I change the function, it dynamically changes in graph. But nothing happen, when I push the button (FileNameSetter) Could you tell me, please, what am I doing wrong.
fil = NotebookDirectory[] <> "Example.tsv" (*hardcode*);
data4 = Import[fil];
data4 = RandomChoice[data4, 2000];
Q4 = (data4[[All, 2]]);(*cars/s*)p4 = (data4[[All, 2]]/
data4[[All, 3]]);(*cars/m*)Qp =
Transpose@{p4, Q4};(*scatter preparation*)
Manipulate
[
(*"Plot region"*)
Show[
ListPlot[Qp, PlotRange -> All,
AxesLabel -> {"p, cars/m", "Q, cars/s"}],
Plot[
{f[p]}, {p, 0, 1}, AxesLabel -> {"p, АТС/метр", ""},
PlotStyle -> {Red, Thick}
],
ImageSize -> plotWidth
],
(*button*)
Style["boundary conditions ", Bold], FileNameSetter[Dynamic[fil]],
(*this way,I set a function.P.S.no problem here,I guess*)
DynamicModule[
{
code =
Hold[f[x_] :>
If[x < 0.05, -6044 x^3 + 231 x^2 + 22.22222222222222 x,
If[x < 0.09, -3755 x^3 + 767 x^2 - 48 x + 1.913758680555557`,
If[x <= 0.7, 1.672 (0.7 - x), 0]]]]
},
With[
{
fn = (
code = #;
ReleaseHold[# /. RuleDelayed -> SetDelayed]
) &
},
Manipulate[
Column[
{
Labeled[
InputField[Dynamic[code, fn], Hold[Expression],
FieldSize -> 80 ], "Q(\[Rho])", Left,
LabelStyle -> Directive[Bold]]
}
],
Initialization :> fn[code]
]
]
]
];
(*/this way, I set a function. P.S. no problem here, I guess*)
Answer
Although the code you posted does not execute as-is, your report that it works on your end as far as the initialization of the input field and plot region go. I will therefore only tackle the problem with FileNameSetter here.
It has been reported before that Manipulate doesn't directly accept FileNameSetter as a control type (Manipulate and FileNameSetter don't want to play nice together), but Szabolcs showed how it can be tweaked to accept it by using a pure function form (see his answer).
In your application, that goes a long way towards solving your problem, but you will want to combine that with two further changes:
- The plotting function will complain if you invoke it before a file has been selected, because there is no valid data set to plot. To fix that, you can either provide a default filename to load at start, or ask the user for one upon initialization. The latter solution seems preferable to me, as it is more self-contained and it won't be broken if you accidentally delete your default file. We will accomplish that using
InitializationwithinManipulate. - The initialization typically works synchronously, i.e.
Manipulatedoesn't wait for it to be done before evaluating the rest of the code. We need to fix that, so the user has time to select a file to plot beforeManipulateproceeds. We can fix that by usingSynchronousInitialization -> Falseas an option toManipulate.
Taken those two points into account, here is a simplified working solution:
Manipulate[
data = Import[filename, "TSV"];
ListPlot[data, PlotRange -> All],
{filename, FileNameSetter[##] &},
Initialization :> (filename = SystemDialogInput["FileOpen"]),
SynchronousInitialization -> False
]

Comments
Post a Comment