PlotLegends` default options - wolfram-mathematica

I'm trying to redefine an option of the PlotLegends package after having loaded it,
but I get for example
Needs["PlotLegends`"]
SetOptions[ListPlot,LegendPosition->{0,0.5}]
=> SetOptions::optnf: LegendPosition is not a known option for ListPlot.
I expect such a thing as the options in the PlotLegends package aren't built-in to Plot and ListPlot.
Is there a way to redefine the default options of the PlotLegends package?

The problem is not really in the defaults for PlotLegends`. To see it, you should inspect the ListPlot implementation:
In[28]:= Needs["PlotLegends`"]
In[50]:= DownValues[ListPlot]
Out[50]=
{HoldPattern[ListPlot[PlotLegends`Private`a:PatternSequence[___,
Except[_?OptionQ]]|PatternSequence[],PlotLegends`Private`opts__?OptionQ]]:>
PlotLegends`Private`legendListPlot[ListPlot,PlotLegends`Private`a,
PlotLegend/.Flatten[{PlotLegends`Private`opts}],PlotLegends`Private`opts]
/;!FreeQ[Flatten[{PlotLegends`Private`opts}],PlotLegend]}
What you see from here is that options must be passed explicitly for it to work, and moreover, PlotLegend option must be present.
One way to achieve what you want is to use my option configuration manager, which imitates global options by passing local ones. Here is a version where option-filtering is made optional:
ClearAll[setOptionConfiguration, getOptionConfiguration, withOptionConfiguration];
SetAttributes[withOptionConfiguration, HoldFirst];
Module[{optionConfiguration}, optionConfiguration[_][_] = {};
setOptionConfiguration[f_, tag_, {opts___?OptionQ}, filterQ : (True | False) : True] :=
optionConfiguration[f][tag] =
If[filterQ, FilterRules[{opts}, Options[f]], {opts}];
getOptionConfiguration[f_, tag_] := optionConfiguration[f][tag];
withOptionConfiguration[f_[args___], tag_] :=
f[args, Sequence ## optionConfiguration[f][tag]];
];
To use this, first define your configuration and a short-cut macro, as follows:
setOptionConfiguration[ListPlot,"myConfig", {LegendPosition -> {0.8, -0.8}}, False];
withMyConfig = Function[code, withOptionConfiguration[code, "myConfig"], HoldAll];
Now, here you go:
withMyConfig[
ListPlot[{#, Sin[#]} & /# Range[0, 2 Pi, 0.1], PlotLegend -> {"sine"}]
]

LegendsPosition works in ListPlot without problems (for me at least). You don't happen to have forgotten to load the package by using Needs["PlotLegends"]`?

#Leonid, I added the possibility to setOptionConfiguration to set default options to f without having to use a short-cut macro.
I use the trick exposed by Alexey Popkov in What is in your Mathematica tool bag?
Example:
Needs["PlotLegends`"];
setOptionConfiguration[ListPlot, "myConfig", {LegendPosition -> {0.8, -0.8}},SetAsDefault -> True]
ListPlot[{#, Sin[#]} & /# Range[0, 2 Pi, 0.1], PlotLegend -> {"sine"}]
Here is the implementation
Options[setOptionConfiguration] = {FilterQ -> False, SetAsDefault -> False};
setOptionConfiguration[f_, tag_, {opts___?OptionQ}, OptionsPattern[]] :=
Module[{protectedFunction},
optionConfiguration[f][tag] =
If[OptionValue#FilterQ, FilterRules[{opts},
Options[f]]
,
{opts}
];
If[OptionValue#SetAsDefault,
If[(protectedFunction = MemberQ[Attributes[f], Protected]),
Unprotect[f];
];
DownValues[f] =
Union[
{
(*I want this new rule to be the first in the DownValues of f*)
HoldPattern[f[args___]] :>
Block[{$inF = True},
withOptionConfiguration[f[args], tag]
] /; ! TrueQ[$inF]
}
,
DownValues[f]
];
If[protectedFunction,
Protect[f];
];
];
];

Related

Performance gain on call chaining?

Do you gain any performance, even if it's minor, by chaining function calls as shown below or is it just coding style preference?
execute() ->
step4(step3(step2(step1())).
Instead of
execute() ->
S1 = step1(),
S2 = step2(S1),
S3 = step3(S2),
step4(S3).
I was thinking whether in the 2nd version the garbage collector has some work to do for S1, S2, S3. Should that apply for the 1st version as well?
They are identical after compilation. You can confirm this by running the erl file through erlc -S and reading the generated .S file:
$ cat a.erl
-module(a).
-compile(export_all).
step1() -> ok.
step2(_) -> ok.
step3(_) -> ok.
step4(_) -> ok.
execute1() ->
step4(step3(step2(step1()))).
execute2() ->
S1 = step1(),
S2 = step2(S1),
S3 = step3(S2),
step4(S3).
$ erlc -S a.erl
$ cat a.S
{module, a}. %% version = 0
...
{function, execute1, 0, 10}.
{label,9}.
{line,[{location,"a.erl",9}]}.
{func_info,{atom,a},{atom,execute1},0}.
{label,10}.
{allocate,0,0}.
{line,[{location,"a.erl",10}]}.
{call,0,{f,2}}.
{line,[{location,"a.erl",10}]}.
{call,1,{f,4}}.
{line,[{location,"a.erl",10}]}.
{call,1,{f,6}}.
{call_last,1,{f,8},0}.
{function, execute2, 0, 12}.
{label,11}.
{line,[{location,"a.erl",12}]}.
{func_info,{atom,a},{atom,execute2},0}.
{label,12}.
{allocate,0,0}.
{line,[{location,"a.erl",13}]}.
{call,0,{f,2}}.
{line,[{location,"a.erl",14}]}.
{call,1,{f,4}}.
{line,[{location,"a.erl",15}]}.
{call,1,{f,6}}.
{call_last,1,{f,8},0}.
...
As you can see, both execute1 and execute2 result in identical code (the only thing different are line numbers and label numbers.

In Mathematica, how to superpose two ListLinePlot?

I was using ListPlot to draw two smooth lines through some data points. But I want to superpose the plot.I learned that the method used by ListPlot for interpolation is to interpolate each coordinate as a function of the list index. So I can not simply plus two
interpolations of my two points.
thanks,
jzm
Here is some text for copy/paste:
myPoints1 = {{1.4620657889458748`,
335.2985577878116`}, {1.4620965802217518`,
103.38351787529564`}, {1.4621942025270345`,
62.5559208248015`}, {1.462354896492246`,
45.566589506360216`}, {1.4625751467402768`,
36.264281440327565`}, {1.4628516301983985`,
30.399003865053114`}, {1.4631812807492346`,
26.367460111951058`}, {1.4635611902991474`,
23.429554855802188`}, {1.4639886111585874`,
21.195443300677702`}, {1.464460983399038`,
19.440829611123966`}, {1.4649759015994719`,
18.02777886500251`}, {1.4655311109490736`,
16.86675689819105`}, {1.466124470097565`,
15.896899417397284`}, {1.4667539758770534`,
15.075547889029616`}, {1.467417728656181`,
14.37183869811537`}, {1.468113935160521`,
13.76291072113658`}, {1.4688409098827062`,
13.231534377122449`}, {1.4695970390339186`,
12.764290193109172`}, {1.4703808152150737`,
12.350655500316538`}, {1.47119080820051`,
11.982259112096562`}, {1.4720256766729714`,
11.652466731657922`}, {1.4728841551349938`,
11.35608813384227`}, {1.4737650210799367`,
11.088805023428025`}, {1.4746670942175184`,
10.846730689594123`}, {1.4755892711659102`,
10.626599181057326`}, {1.4765305432312286`,
10.425844517518913`}, {1.4774899140433866`,
10.242189544437958`}, {1.4784664768294848`,
10.07388845283117`}, {1.4794593535682306`,
9.91948469998374`}, {1.480467656424019`,
9.777491405153027`}, {1.4814906043125302`,
9.646805534544441`}, {1.4825273964568986`,
9.526291139015447`}, {1.4835772786981303`,
9.414764726544572`}, {1.4846395968104766`,
9.311395888282872`}, {1.4857136927436698`,
9.215545785306015`}, {1.4867989654798728`,
9.12678547130485`}, {1.487894785812934`,
9.0445918653539`}, {1.489000547636927`,
8.968341543739935`}, {1.49011571024499`,
7.71616343700933`}, {1.4912397307928495`,
4.4771368717931965`}, {1.4930948425223702`,
2.7599903709003706`}, {1.4972705714803425`, 2.137733395169292`}};
myPoints2 = {{1.9550995254889463,
0.7164793699550908}, {1.9391287471262355,
0.41710931241140287}, {1.9139528821159193,
0.3490726623599497}, {1.884617534719042,
0.3308820126668058}, {1.8540123750258504,
0.33265450551933234}, {1.8237456098779754,
0.3452794413751484}, {1.7946805323610866,
0.36513934480358856}, {1.7672498634600862,
0.3905924543768967}, {1.7416378319498413,
0.42085584504202456}, {1.717886011205134,
0.45557423825820337}, {1.6959554065943552,
0.49463019895914645}, {1.675763216373194,
0.5380524422510392}, {1.6572047192352064,
0.5859687470445493}, {1.6401662975943239,
0.6385812315738714}, {1.6245331447101943,
0.6961532977719818}, {1.6101937002933333,
0.7590036122922289}, {1.5970420916568349,
0.8275045669571167}, {1.5849793700525658,
0.9020832266507519}, {1.5739139593253322,
0.9832255360102758}, {1.5637616875683809,
1.071482155332956}, {1.5544455489784297,
1.1674755467368436}, {1.5458952859916812,
1.2719109855898907}, {1.538046945587126,
1.3855881585132812}, {1.5308423787211705,
1.5094157124835617}, {1.5242287288899015,
1.6444321762294256}, {1.5181579889629853,
1.7918272163885938}, {1.512586535548833,
1.952969437543702}, {1.5074747129386745,
2.1294427702228105}, {1.5027864632086367,
2.3230885849762424}, {1.4984889655043911,
2.536061738604728}, {1.4945523307439923,
2.7708992557015053}, {1.4909493139037207,
3.0306073328297867}, {1.4876550515968234,
3.3187795649748657}, {1.4846468371914137,
3.6397480437107252}, {1.481903916697491,
3.9987774524193394}, {1.4794072959177726,
4.4023273698572325}, {1.4771395719585305,
4.858408392792459}, {1.4750847772800355,
5.37708563628973}, {1.4732282431253443,
5.971204815109932}, {1.4715564902918326,
6.657415608955233}, {1.4700571242943155,
7.457674059555506}, {1.4687187279247118,
8.40154880208839}, {1.4675307832019475,
9.529729255387132}, {1.4664835796976867,
10.899794007715421}, {1.46556811155878,
12.596323274840168}, {1.4647760611386595,
14.748618559900901}, {1.4640997339059703,
17.564564972128032}, {1.463531979901696,
21.401490423013954}, {1.4630661880201312,
26.92897502098747}, {1.462696204020183,
35.566591773864054}, {1.4624163023794263,
50.94289950596402}, {1.462221186527755,
85.91265697099175}, {1.4621058905589708,
243.1565306412274}, {1.4620657889458748, 335.2985577878116}};
what I want is not
Show[ListPlot[myPoints1, Joined -> True, Mesh -> Full],
ListPlot[myPoints2, Joined -> True, Mesh -> Full]]
don't know how to get the plot of the value's superpostion of the two plot.Please help!:)
The meaning of "superpostion" is to get the plus of the value of the two curves at every x-axis.
Sounds like you want something like this in order to "plus" your lines.
it1 = Interpolation[myPoints1];
it2 = Interpolation[myPoints2];
t1 = Table[it1[i], {i, 1.467, 1.497, 0.001}];
t2 = Table[it2[i], {i, 1.467, 1.497, 0.001}];
t3 = Transpose[{Range[1.467, 1.497, 0.001], t1 + t2}];
ListPlot[{myPoints1, myPoints2, t3}, Joined -> True,
PlotRange -> {{1.467, 1.497}, {0, 30}}, PlotMarkers -> Automatic]

Reading UTF-8 text files with ReadList

Is it possible to use ReadList to read UTF-8 (or any other) encoded text files using ReadList[..., Word], or is it ASCII-only? If it's ASCII-only, is it possible to "fix" the encoding of the already read data with good performance (i.e. preserving the performance advantages of ReadList over Import)?
Import[..., CharacterEncoding -> "UTF8"] works but it's quite a bit slower than ReadList. $CharacterEncoding has no effect on ReadList
Download a sample UTF-8 encoded file here.
For testing performance on a large input, see the test file in this question.
Here are the timings of the answers on a large-ish text file:
Import
In[2]:= Timing[
data = Import[file, "Text"];
]
Out[2]= {5.234, Null}
Heike
In[4]:= Timing[
data = ReadList[file, String];
FromCharacterCode[ToCharacterCode[data], "UTF8"];
]
Out[4]= {4.328, Null}
Mr. Wizard
In[5]:= Timing[
string = FromCharacterCode[BinaryReadList[file], "UTF-8"];
]
Out[5]= {2.281, Null}
This seems to work
FromCharacterCode[ToCharacterCode[ReadList["raw.php.txt", Word]], "UTF-8"]
The timings I get for the linked test file are
FromCharacterCode[ToCharacterCode[ReadList["test.txt", Word]], "UTF-8"]); // Timing
(* ==> {0.000195, Null} *)
Import["test.txt", "Text"]; // Timing
(* ==> {0.01784, Null} *)
If I leave out Word, this works:
$CharacterEncoding = "UTF-8";
ReadList["UTF8.txt"]
This however is a failure, because the data is not read as strings.
Please try this on a larger file and report its performance:
FromCharacterCode[BinaryReadList["UTF8.txt"], "UTF-8"]

Self-destructive Button inside Column

How to create a Button which will be displayed only when the value of some global FrontEnd setting is False and will self-destruct with entire row of the Column after pressing it setting this value to True?
I need something like this:
Column[{"Item 1", "Item 2",
Dynamic[If[
Last#Last#Options[$FrontEnd, "VersionedPreferences"] === False,
Button["Press me!",
SetOptions[$FrontEnd, "VersionedPreferences" -> True]],
Sequence ## {}]]}]
But with this code the Button does not disappear after pressing it. Is it possible to make it self-destructive?
The final solution based on ideas by belisarius and mikuszefski:
PreemptProtect[SetOptions[$FrontEnd, "VersionedPreferences" -> False];
b = True];
Dynamic[Column[
Join[{"Item 1", "Item 2"},
If[Last#Last#Options[$FrontEnd, "VersionedPreferences"] === False &&
b == True, {Button[
Pane[Style[
"This FrontEnd uses shared preferences file. Press this \
button to set FrontEnd to use versioned preferences file (all the \
FrontEnd settings will be reset to defaults).", Red], 300],
AbortProtect[
SetOptions[$FrontEnd, "VersionedPreferences" -> True];
b = False]]}, {}]], Alignment -> Center],
Initialization :>
If[! Last#Last#Options[$FrontEnd, "VersionedPreferences"], b = True,
b = False]]
The key points are:
introducing additional Dynamic variable b and binding it with the value of Options[$FrontEnd, "VersionedPreferences"],
wrapping entire Column construct
with Dynamic instead of using
Dynamic inside Column.
Perhaps
PreemptProtect[SetOptions[$FrontEnd, "VersionedPreferences" -> False]; b = True];
Column[{"Item 1", "Item 2", Dynamic[
If[Last#Last#Options[$FrontEnd, "VersionedPreferences"]===False && b == True,
Button["Here!", SetOptions[$FrontEnd, "VersionedPreferences"->True];b=False],
"Done"]]}]
Edit
Answering your comment. Please try the following. Encompassing the Column[ ] with Dynamic[ ] allows resizing it:
PreemptProtect[SetOptions[$FrontEnd, "VersionedPreferences" -> False]; b = True];
Dynamic[
Column[{
"Item 1",
"Item 2",
If[Last#Last#Options[$FrontEnd, "VersionedPreferences"] === False && b == True,
Button["Press me!", SetOptions[$FrontEnd, "VersionedPreferences" -> True]; b=False],
Sequence ## {}]}]]
Hmm, dunno if I get it right, but maybe this:
x = True;
Dynamic[Column[{Button["reset", x = True],
If[x, Button["Press me", x = False]]}]
]

Nice formatting of numbers inside Messages

When printing string with StyleBox by default we get nicely formatted numbers inside string:
StyleBox["some text 1000000"] // DisplayForm
I mean that the numbers look as if would have additional little spaces: "1 000 000".
But in Messages all numbers are displayed without formatting:
f::NoMoreMemory =
"There are less than `1` bytes of free physical memory (`2` bytes \
is free). $Failed is returned.";
Message[f::NoMoreMemory, 1000000, 98000000]
Is there a way to get numbers inside Messages to be formatted?
I'd use Style to apply the AutoNumberFormatting option:
You can use it to target specific messages:
f::NoMoreMemory =
"There are less than `1` bytes of free physical memory (`2` bytes is free). $Failed is returned.";
Message[f::NoMoreMemory,
Style[1000000, AutoNumberFormatting -> True],
Style[98000000, AutoNumberFormatting -> True]]
or you can use it with $MessagePrePrint to apply it to all the messages:
$MessagePrePrint = Style[#, AutoNumberFormatting -> True] &;
Message[f::NoMoreMemory, 1000000, 98000000]
I think you want $MessagePrePrint
$MessagePrePrint =
NumberForm[#, DigitBlock -> 3, NumberSeparator -> " "] &;
Or, incorporating Sjoerd's suggestion:
With[
{opts =
AbsoluteOptions[EvaluationNotebook[],
{DigitBlock, NumberSeparator}]},
$MessagePrePrint = NumberForm[#, Sequence ## opts] &];
Adapting Brett Champion's method, I believe this allows for copy & paste as you requested:
$MessagePrePrint = StyleForm[#, AutoNumberFormatting -> True] &;

Resources