Mathematica, FrameTicks inconsistency across different kinds of plots - wolfram-mathematica

I came across some unexpected inconsistencies when further developing the solution to an earlier question:
How can I show % values on the y axis of a plot?
This seemed different enough to merit a new post.
Starting with the same data:
data = {{{2010, 8, 3},
0.}, {{2010, 8, 31}, -0.052208}, {{2010, 9, 30},
0.008221}, {{2010, 10, 29}, 0.133203}, {{2010, 11, 30},
0.044557}, {{2010, 12, 31}, 0.164891}, {{2011, 1, 31},
0.055141}, {{2011, 2, 28}, 0.114801}, {{2011, 3, 31},
0.170501}, {{2011, 4, 29}, 0.347566}, {{2011, 5, 31},
0.461358}, {{2011, 6, 30}, 0.244649}, {{2011, 7, 29},
0.41939}, {{2011, 8, 31}, 0.589874}, {{2011, 9, 30},
0.444151}, {{2011, 10, 31}, 0.549095}, {{2011, 11, 30},
0.539669}};
I defined a way to make FrameTicks with percentages built on the contributions and insights offered in the last post:
myFrameTicks =
Table[
{k/10., ToString#(10 k) <> "%"},
{
k,
IntegerPart[Floor[Min#data[[All, 2]], .1]*10],
IntegerPart[Ceiling[Max#data[[All, 2]], .1]*10]
}
];
Now look at two plots of the same data using the same FrameTicks:
DateListPlot[data, FrameTicks -> {{myFrameTicks, None}, {Automatic, None}}]
ListPlot[data[[All, 2]], FrameTicks -> {{myFrameTicks, None}, {Automatic, None}}]
So, why don't both of these plots show the frame ticks as percentage (e.g., 60%) like the first one does?
I might have missed something obvious (not the first time). Also, this approach doesn't appear to work when used with ListLinePlot or BarChart, both of which seem to accept a FrameTicks attribute.

DateListPlot defaults to Frame->True. ListPlot defaults to Frame->False. It is displaying Ticks, not FrameTicks.
Try setting the Frame to true:
DateListPlot[data,
FrameTicks -> {{myFrameTicks, None}, {Automatic, None}}]
ListPlot[data[[All, 2]],
Frame -> True,
FrameTicks -> {{myFrameTicks, None}, {Automatic, None}}]

We have FrameTicks for Frame, and Ticks for Axes, so in addition to David's solution of turning on the frame for ListPlot, you could instead specify your function for Ticks:
ListPlot[data[[All, 2]], Ticks -> {Automatic, myFrameTicks}]
(Note the difference in ordering.)

Related

Some plotmarkers appear to be cut off in Mathematica 13.2.0 and 13.2.1 but look ok in Mathematica 11.0

We have noticed that some of the plotmarkers in a listplot get cut off.
We are using the below global setting to render plots with the same size as they were in Mathematica 11.0. Images appeared much larger in Mathematica 13.2 without this setting.
CurrentValue[$FrontEnd, "ScreenResolutionCompatibilityMode"] = True
Here's an example of a ListPlot with Plotmarkers
ListPlot[{{1, 2, 3, 5, 8}, {2, 3, 6, 9, 10}, {4, 5, 7, 10, 12}},
PlotMarkers -> {Graphics[{EdgeForm[], Disk[]}, ImageSize -> 10],
Graphics[],
Graphics[{EdgeForm[], Polygon[{{1, 0}, {0, Sqrt[3]}, {-1, 0}}]},
ImageSize -> 10],
Graphics[{EdgeForm[],
Rotate[Polygon[{{1, 0}, {0, Sqrt[3]}, {-1, 0}}], 180 Degree]},
ImageSize -> 10]}]
Screenshot:
PlotMarkers Cut Off
Here's another example:
ListPlot[{{1, 2, 3, 5, 8}, {2, 3, 6, 9, 10}, {4, 5, 7, 10, 12}},
PlotMarkers -> {Automatic, Large}] (*Plotmarkers are getting cut off*)
Screenshot:
Plotmarkers
I have already tried adding ImagePadding-> 1 as suggested here plotting - Custom PlotMarkers with Graphics get cut - Mathematica Stack Exchange but that makes the plotmarkers appear small so that may not be the best solution for us.
Please advise if there are any alternatives way to fix this.

Searching for certain triples in a list

Let’s assume we have a list of elements of the type {x,y,z} for x, y
and z integers. And, if needed x < y < z.
We also assume that the list contains at least 3 such triples.
Can Mathematica easily solve the following problem?
To detect at least one triple of the type {a,b,.}, {b,c,.} and {a,c,.}?
I am more intereseted in an elegant 1-liner than computational efficient solutions.
If I understood the problem, you want to detect triples not necessarily following one another, but generally present somewhere in the list. Here is one way to detect all such triples. First, some test list:
In[71]:= tst = RandomInteger[5,{10,3}]
Out[71]= {{1,1,0},{1,3,5},{3,3,4},{1,2,1},{2,0,3},{2,5,1},{4,2,2},
{4,3,4},{1,4,2},{4,4,3}}
Here is the code:
In[73]:=
Apply[Join,ReplaceList[tst,{___,#1,___,#2,___,#3,___}:>{fst,sec,th}]&###
Permutations[{fst:{a_,b_,_},sec:{b_,c_,_},th:{a_,c_,_}}]]
Out[73]= {{{1,4,2},{4,3,4},{1,3,5}},{{1,4,2},{4,2,2},{1,2,1}}}
This may perhaps satisfy your "one-liner" requirement, but is not very efficient. If you need only triples following one another, then, as an alternative to solution given by #Chris, you can do
ReplaceList[list,
{___, seq : PatternSequence[{a_, b_, _}, {b_, c_, _}, {a_,c_, _}], ___} :> {seq}]
I don't know if I interpreted your question correctly but suppose your list is something like
list = Sort /# RandomInteger[10, {20, 3}]
(*
{{3, 9, 9}, {0, 5, 6}, {3, 4, 8}, {4, 6, 10}, {3, 6, 9}, {1, 4, 8},
{0, 6, 10}, {2, 9, 10}, {3, 5, 9}, {6, 7, 9}, {0, 9, 10}, {1, 7, 10},
{4, 5, 10}, {0, 2, 5}, {0, 6, 7}, {1, 8, 10}, {1, 8, 10}}
*)
then you could do something like
ReplaceList[Sort[list],
{___, p:{a_, b_, _}, ___, q:{a_, c_, _}, ___, r:{b_, c_, _}, ___} :> {p, q, r}]
(* Output:
{{{0, 2, 5}, {0, 9, 10}, {2, 9, 10}}, {{3, 4, 8}, {3, 5, 9},
{4, 5, 10}}, {{3, 4, 8}, {3, 6, 9}, {4, 6, 10}}}
*)
Note that this works since it is given that for any element {x,y,z} in the original list we have x<=y. Therefore, for a triple {{a,b,_}, {a,c,_}, {b,c,_}} \[Subset] list we know that a<=b<=c. This means that the three elements {a,b,_}, {a,c,_}, and {b,c,_} will appear in that order in Sort[list].
To match triples "of the type {a,b,.}, {b,c,.} and {a,c,.}":
list = {{34, 37, 8}, {74, 32, 65}, {48, 77, 18}, {77, 100, 30},
{48, 100, 13}, {100, 94, 55}, {48, 94, 73}, {77, 28, 12},
{90, 91, 51}, {34, 5, 32}};
Cases[Partition[list, 3, 1], {{a_, b_, _}, {b_, c_, _}, {a_, c_, _}}]
(Edited)
(Tuples was not the way to go)
Do you require something like:
list = RandomInteger[10, {50, 3}];
Cases[Permutations[
list, {3}], {{a_, b_, _}, {b_, c_, _}, {a_, c_, _}} /; a < b < c]
giving
{{{0, 1, 2}, {1, 5, 2}, {0, 5, 4}},
{{2, 3, 5},{3, 4, 10}, {2, 4, 5}},
{{6, 8, 10}, {8, 10, 10},{6, 10, 0}},
{{2, 4, 5}, {4, 8, 2}, {2, 8, 5}},
{{2, 4, 5}, {4, 7, 7}, {2, 7, 3}},
{{0, 2, 2}, {2, 7, 3}, {0, 7, 2}},
{{0, 2, 1}, {2, 7, 3}, {0, 7, 2}}}
or perhaps (as other have interpreted the question):
Cases[Permutations[
list, {3}], {{a_, b_, _}, {b_, c_, _}, {a_, c_, _}}];

Apply EuclideanDistance at a certain level in Mathematica

Please consider:
daList = {{{21, 18}, {20, 18}, {18, 17}, {20, 15}},
{{21, 18}, {20, 18}, {21, 14}, {21, 14}}};
I would like to compute the distance between each point in the 2 sub-lists of that list:
Yet I need to use a Function to apply at the correct level:
Function[seqNo,
EuclideanDistance[#, {0, 0}] & /# daList[[seqNo]]] /#
Range[Length#daList]
out = {{3 Sqrt[85], 2 Sqrt[181], Sqrt[613], 25}, {3 Sqrt[85], 2 Sqrt[181],
7 Sqrt[13], 7 Sqrt[13]}}
Is there a way to avoid this heavy function there?
To specify the level avoiding my Function with seqNo as argument? :
EuclideanDistance[#, {0, 0}] & /# daList
out={EuclideanDistance[{{21, 18}, {20, 18}, {18, 17}, {20, 15}}, {0, 0}],
EuclideanDistance[{{21, 18}, {20, 18}, {21, 14}, {21, 14}}, {0, 0}]}
Have you tried the Level specification in Map?
Map[EuclideanDistance[#, {0, 0}] &, daList, {2}]
gives
{{3 Sqrt[85],2 Sqrt[181],Sqrt[613],25},{3 Sqrt[85],2 Sqrt[181],7 Sqrt[13],7 Sqrt[13]}}
To complement the answer of #Markus: if your daList is very large and numerical, the following will be much faster (like 30x), although somewhat less general:
Sqrt#Total[daList^2,{3}]
Here is an example:
In[17]:= largeDaList = N#RandomInteger[30,{100000,4,2}];
In[18]:= Map[EuclideanDistance[#,{0,0}]&,largeDaList,{2}]//Short//Timing
Out[18]= {0.953,{{31.7648,34.6699,20.3961,31.305},<<99998>>,{<<18>>,<<2>>,0.}}}
In[19]:= Sqrt#Total[largeDaList^2,{3}]//Short//Timing
Out[19]= {0.031,{{31.7648,34.6699,20.3961,31.305},<<99998>>,{<<18>>,<<2>>,0.}}}
The reason is that functions like Power and Sqrt are Listable, and you push the iteration into the kernel. Functions like Map can also auto-compile the mapped function in many cases, but apparently not in this case.
EDIT
Per OP's request, here is a generalization to the case of non-trivial reference point:
refPoint = {3, 5};
Sqrt#Total[#^2, {3}] &#Transpose[Transpose[daList, {3, 2, 1}] - refPoint, {3, 2, 1}]
It is still fast, but not as concise as before. For comparison, here is the code based on Map- ping, which only needs a trivial modification here:
Map[EuclideanDistance[#, refPoint] &, daList, {2}]
The performance difference remains of the same order of magnitude, although the vectorized solution slows down a bit due to the need for non-trivial transpositions.

Logarithmic Slider Control in Mathematica

I'm making a small interface for calculating voltage dividers in Mathematica. I have two sliders (z1 & z2) that represent the resistor values and a couple of sliders to represent Vin as a sinusoid.
The issue is that the range of available resistor values (in the real world) is roughly logarithmic on {r, 100, 1,000,000}. If I set my slider range to r, however, it's impractical to select common low resistor values in approx. {100, 10,000}.
Is it possible to create a slider that sweeps through a logarithmic range?
Manipulate[
Grid[{{Plot[(VinRCos[t] + VinC), {t, -3, 9},
PlotRange -> {-1, VMax}, AxesLabel -> {t, Vin}]}, {Plot[
z2/(z1 + z2)(VinR*Cos[t] + VinC), {t, -3, 9},
PlotRange -> {-1, VMax}, AxesLabel -> {t, Vout}]}},
ItemSize -> 20],
{{z1, 10000}, 10, 1000000, 10}, {z1}, {{z2, 10000}, 10,
1000000}, {z2}, Delimiter, {{VinR, 2.5}, 0,
5}, {VinR}, {{VinC, 2}, -VMax, VMax}, {VinC}]
Michael's answer is probably the best, i.e. just get the user to specify the exponent. An alternate solution is to make a LogSlider type command. Here's a simple example:
LogSlider[{v:Dynamic[var_], v0_?Positive}, {min_?Positive, max_?Positive},
base_:10, options___] := DynamicModule[{ev}, Dynamic[
var = base^ev;
Slider[Dynamic[ev], Log[base, {min, max}]]]]
LogSlider[v:Dynamic[var_], {min_?Positive, max_?Positive},
base_:10, options___] := LogSlider[{v, min}, {min, max}]
The function only has a subset of the flexibility of Slider and will have to be extended if you want custom step sizes etc...
You then modify your Manipulate by specifying the variables using
{{z1, 10000}, 10, 1000000, LogSlider[##]&} etc...
A simple fix is to just make the slider manipulate the exponent, and plug in e.g. 10^z1 where you need the actual value:
Manipulate[10^z1, {{z1, 5}, 2, 6}] (* 100 to 1M *)
In your particular case, you could of course also input a list of standard resistor values to pick from:
Manipulate[z1, {z1, {100, 110, 120, 130, 150, 160, 180, 200, 220, 240, 270}}]
HTH!
Here is my final result:
Manipulate[
Evaluate[Round[10^Z2]/(Round[10^Z1] + Round[10^Z2])*Vin] "V",
{{Z1, 5}, 2, 6},
Pane["Z1 = " Dynamic[Round[10^Z1] "[CapitalOmega]"],
ImageMargins -> {{2.5, 0}, {3, 0}}],
{{Z2, 5}, 2, 6},
Pane["Z2 = " Dynamic[Round[10^Z2] "[CapitalOmega]"],
ImageMargins -> {{2.5, 0}, {0, -5}}], {{Vin, 2.5}, 0, VMax},
Pane["Vin = " Dynamic[Vin "V"], ImageMargins -> {{0, 0}, {0, -5}}]]
Here is a start to LogSlider that produces the standard two-way behavior the other controls have.
LogSlider[Dynamic[x_], max_] :=
Module[{exp},
Dynamic[exp = Log[max, x];
Slider[Dynamic[exp, (exp = #; x = max^exp) &]]]]
{LogSlider[Dynamic#x, 10^6], Dynamic#x}

Sort all levels of expression

What's a good way to Sort all levels of an expression? The following does what I want when expression has rectangular structure, but I'd like it to work for non-rectangular expressions as well
Map[Sort, {expr}, Depth[expr] - 1]
For instance, the following should print True
sorted = deepSort[{{{1, 3, 8}, {3, 7, 6}, {10, 4, 9}, {3, 8, 10,
6}, {8, 2, 5, 10}, {8, 5, 10,
9}}, {{{1, 3, 8}, {3, 8, 10, 6}}, {{3, 7, 6}, {3, 8, 10,
6}}, {{10, 4, 9}, {8, 5, 10, 9}}, {{3, 8, 10, 6}, {8, 2, 5,
10}}, {{8, 2, 5, 10}, {8, 5, 10, 9}}}}];
checkSortedLevel[k_] := Map[OrderedQ, sorted, {k}];
And ## Flatten[checkSortedLevel /# Range[0, 2]]
deepSort[expr_] := Map[Sort, expr, {0, -2}]
Note that this will work even if your expr contains heads other than List.
Should you have an expression that contains heads other than List, and you do not want to sort those, this may be useful.
expr /. List :> Composition[Sort, List]

Resources