24
$\begingroup$

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.

$\endgroup$
  • 4
    $\begingroup$ I had missed this question until today. Let me just note that the same thing is seen in version 9.0.1, 8.0.4, 7.0.1 in the slightly different form of Ticks::ticks : <valid explicit tick specification> is not a valid tick specification. It is correct in 5.2. You are probably right in thinking that AbsoluteOptions has been abandoned. $\endgroup$ – Oleksandr R. May 17 '15 at 15:09
  • 2
    $\begingroup$ @Oleksandr Thanks for the report: in supports my suspicion that FullGraphics and AbsoluteOptions have never been (properly) updated for version 6+ graphics. $\endgroup$ – Mr.Wizard May 17 '15 at 15:11
  • 2
    $\begingroup$ @QuantumDot I have mostly given up hope on AbsoluteOptions. The fundamental problem with it is that these things are computed by the front end with information about things like screen resolution, font size, and other things that affect what fits on the screen. AbsoluteOptions has always just given an approximation. So I see the difficulties. But I am also disappointed that there seems to be no effort to deal with them. $\endgroup$ – Szabolcs Aug 9 '16 at 11:35
  • 2
    $\begingroup$ @QuantumDot Szabolcs kindly went through my list of bugs and updated their status. Not a single one has been marked fixed. I continue to be disappointed in the direction this software is heading. I had genuinely hoped that after the expansion of functions in version 10 that the next release would finally focus on improving the functions that already exist and strengthening the core language, perhaps with better pattern matching etc. I kind of feel foolish for keeping that hope now as it seems its going to be more of the same. $\endgroup$ – Mr.Wizard Aug 9 '16 at 11:56
  • 3
    $\begingroup$ Apparently Wolfram prides himself with quantity over quality. Here is an excerpt from his blog: "there are 555 completely new functions that we’re adding in Version 11—representing a huge amount of new functionality (by comparison, Version 1 had a total of 551 functions altogether)..." It includes (in my view) trash functions like ReIm and PerfectNumber. $\endgroup$ – QuantumDot Aug 9 '16 at 12:04
6
$\begingroup$

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

$\endgroup$
  • $\begingroup$ In my system (version 11.0.0) fixOptions // Definition returns Null and FullAxesDump`fixOptions // Definition returns the definition even without System`Private`NewContextPath. $\endgroup$ – Alexey Popkov Feb 18 '17 at 7:37
  • $\begingroup$ @AlexyPopkov Not sure why I had an issue, then. I should have tried quitting my kernel first to see if that fixed my context switching issue. I'll update my answer. $\endgroup$ – Carl Woll Feb 18 '17 at 7:50
  • $\begingroup$ Thank you! Would you perhaps be willing to tackle a related question of mine? mathematica.stackexchange.com/q/83648/121 This one appears to be a sub-part of it. And the overarching question remains as to the long term intent for this function. $\endgroup$ – Mr.Wizard Feb 18 '17 at 11:05
  • $\begingroup$ Change FullAxes to FullGraphics, and add FrameLabel. $\endgroup$ – Carl Woll Feb 18 '17 at 15:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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