Skip to main content

graphics - More Ticks::ticks errors in AbsoluteOptions in v10


Bug introduced in 7.0 or earlier and persisting through 11.3




While the specific bug affecting Plot described in AbsoluteOptions prints error messages in V10 has been fixed in 10.0.2 there remain problems with AbsoluteOptions. The first one I note is failure in resolving function-based FrameTicks as used by LogPlot:


LogPlot[x^x, {x, 1, 5}, Frame -> True] // AbsoluteOptions

enter image description here


In the full output the FrameTicks option appears as:


FrameTicks -> {{}, {}, {}, {}}


More errors are seen here:


ReliefPlot[RandomReal[1, {10, 10}]] // AbsoluteOptions

enter image description here


This despite the fact that the plot has no ticks. Automatic also fails, e.g.:


ParametricPlot[r t, {r, 0, 5}, {t, 1, 2}] // AbsoluteOptions

enter image description here





Oleksandr notes in the comments that a similar problem has affected versions 7, 8, and 9 as well, though the issued messages are a bit different. I am therefore updating the header to introduced in 7.0 or earlier.



Answer



This is what I believe the situation to be. AbsoluteOptions uses FullAxes under the hood. It turns out that FullAxes is still expecting Frame/FrameLabel options to be specified using the old Frame -> {b, l, t, r} syntax instead of the new Frame->{{l, r}, {b, t}} syntax. This is why FullAxes issues messages and doesn't work. This means the solution is simply to fix these options before running AbsoluteOptions/FullAxes on the graphic.


(update to fix PlotRange as well)


It turns out that the function PlotRange also has an issue with some "malformed" plot ranges, so I updated the code to handle that as well.


Here is the revised code:


Begin["FullAxesDump`"];

With[{graphic = ListLogPlot[{10, 100}]},
If[Quiet @ TrueQ @ Check[FullAxes @ graphic, True],

Unprotect[FullAxes];
FullAxes[arg_] /; !TrueQ@$FACheck := Block[{$FACheck=True},
FullAxes[fixOptions@arg]
];
Protect[FullAxes];
]
]

With[{graphic = Graphics[{}, GridLines->None, PlotRange->{{0, 1}, {All, All}}]},
If[Quiet @ TrueQ @ Check[PlotRange[graphic], True],

Unprotect[PlotRange];
PlotRange[arg_] /; !TrueQ@$FACheck := Block[{$FACheck=True},
PlotRange[fixOptions[arg]]
];
Protect[PlotRange];
]
]

fixOptions[x_]:=x
fixOptions[(tag:Graphics3D|Graphics)[g_,opts__]] := tag[

g,
Sequence@@ReplaceAll[
{opts},
Rule[h:Frame|FrameTicks|PlotRange,rhs_] :> h->fixRule[h,rhs]
],
Frame->False, Axes->False
]

fixRule[Frame|FrameTicks, {{l_,r_},{b_,t_}}] := {b,l,t,r}
fixRule[Frame|FrameTicks, {d_,s_}] := {d,Automatic,s,Automatic}


fixRule[PlotRange, a_List] := Replace[a, {All, All}->All, {1}]

fixRule[_,rhs_]:=rhs

End[];

Some comments:





  1. I initally used System`Private`NewContextPath and System`Private`RestoreContextPathbecause I had trouble with contexts of my variable names, but that must have been a transient thing related to earlier code.




  2. I only redefine FullAxes if using FullAxes on a ListPlot issues messages. This means that if you want to change the code after running it, you will need to first clear the new FullAxes downvalue that is created by the code. Something along the lines of Unprotect[FullAxes]; Clear[FullAxes]; Protect[FullAxes];




  3. I use the foo /; ! TrueQ@flag := Block[{flag = True}, foo] trick so that the options get tweaked, and then the existing kernel code for foo gets run.




  4. It turns out that Frame -> False needs to get explicitly added to the options so that FullAxes realizes that there really isn't a Frame, and it must process the Ticks/Axes code. Without Frame -> False, the FullAxes code turns Axes -> True into Axes -> {False, False}. Note that options handling uses the first instance of an option, so adding the default (Frame -> False) at the end should not affect output.





I think that's enough explanation. Here is what happens after loading the above code:


AbsoluteOptions[LogPlot[x^x, {x, 1, 5}, Frame -> True], FrameTicks];

AbsoluteOptions[ReliefPlot[RandomReal[1, {10, 10}]]];

AbsoluteOptions[ParametricPlot[r t, {r, 0, 5}, {t, 1, 2}]];

No error messages, although I don't claim that this fixes all cases where AbsoluteOptions issues messages. A similar treatment is possible for FullGraphics



Comments

Popular posts from this blog

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

How to thread a list

I have data in format data = {{a1, a2}, {b1, b2}, {c1, c2}, {d1, d2}} Tableform: I want to thread it to : tdata = {{{a1, b1}, {a2, b2}}, {{a1, c1}, {a2, c2}}, {{a1, d1}, {a2, d2}}} Tableform: And I would like to do better then pseudofunction[n_] := Transpose[{data2[[1]], data2[[n]]}]; SetAttributes[pseudofunction, Listable]; Range[2, 4] // pseudofunction Here is my benchmark data, where data3 is normal sample of real data. data3 = Drop[ExcelWorkBook[[Column1 ;; Column4]], None, 1]; data2 = {a #, b #, c #, d #} & /@ Range[1, 10^5]; data = RandomReal[{0, 1}, {10^6, 4}]; Here is my benchmark code kptnw[list_] := Transpose[{Table[First@#, {Length@# - 1}], Rest@#}, {3, 1, 2}] &@list kptnw2[list_] := Transpose[{ConstantArray[First@#, Length@# - 1], Rest@#}, {3, 1, 2}] &@list OleksandrR[list_] := Flatten[Outer[List, List@First[list], Rest[list], 1], {{2}, {1, 4}}] paradox2[list_] := Partition[Riffle[list[[1]], #], 2] & /@ Drop[list, 1] RM[list_] := FoldList[Transpose[{First@li...

front end - keyboard shortcut to invoke Insert new matrix

I frequently need to type in some matrices, and the menu command Insert > Table/Matrix > New... allows matrices with lines drawn between columns and rows, which is very helpful. I would like to make a keyboard shortcut for it, but cannot find the relevant frontend token command (4209405) for it. Since the FullForm[] and InputForm[] of matrices with lines drawn between rows and columns is the same as those without lines, it's hard to do this via 3rd party system-wide text expanders (e.g. autohotkey or atext on mac). How does one assign a keyboard shortcut for the menu item Insert > Table/Matrix > New... , preferably using only mathematica? Thanks! Answer In the MenuSetup.tr (for linux located in the $InstallationDirectory/SystemFiles/FrontEnd/TextResources/X/ directory), I changed the line MenuItem["&New...", "CreateGridBoxDialog"] to read MenuItem["&New...", "CreateGridBoxDialog", MenuKey["m", Modifiers-...