5
$\begingroup$

If, for example,

g = Histogram[RandomVariate[NormalDistribution[0, 1], 200]];

...I want to extract an absolute (abscissa) Tick specification from g. (The RHS above is just a convenient example, straight from the docs for Histogram.)

FullGraphics and AbsoluteOptions are basically useless for this.

I also tried to extract an absolute PlotRange spec from g, but, again, nothing I tried worked. (The idea here was that, maybe, I could pass the extracted PlotRange spec to a suitable dummy Plot expression from whose output I may be able to extract an absolute abscissa Tick spec from.)

$\endgroup$
1
  • 1
    $\begingroup$ After examination of FullForm[g]: the PlotRange can be extracted with Cases[g, x : Rule[PlotRange, ___] :> x, Infinity]. The Rules for Ticks and FrameTicks are, however, expressed in terms of Automatic. Interestingly, AbsoluteOptions[g, PlotRange] gives the PlotRange in the error message, but not as output, though. $\endgroup$ Commented Dec 4, 2016 at 19:02

2 Answers 2

5
$\begingroup$

I also tried to extract an absolute PlotRange spec from g:

SeedRandom[1]
dd = RandomVariate[NormalDistribution[0, 1], 200];
g = Histogram[dd]

enter image description here

1. Use Charting`CommonDump`getplotrange with Options[g, AxesOrigin]:

prF1 = Charting`CommonDump`getplotrange[#, AxesOrigin /. Options[#, AxesOrigin]] &;

prF1 @g

{{-2.5, 3.}, {0, 45.}}

2. Post-process the box expressions of g to extract the bounding boxes:

ClearAll[prF2]
prF2 = Through[{Min, Max}@#] & /@ Transpose[
     Join @@ Cases[# // ToBoxes, RectangleBox[x_, y_, ___] :> {x, y}, ∞]] &;

prF2 @ g

{{-2.5, 3.}, {0, 45}}

Legended[Show[g, GridLines -> prF1[g], GridLinesStyle -> Red, 
  Axes -> False, Method -> {"GridLinesInFront" -> True}, 
  PlotRangePadding -> {{3, 3}, {5, 10}}, ImagePadding -> 20, 
  Frame -> True, FrameTicks -> Thread[{Reverse@prF1[g], None}]], 
 Panel[TableForm[prF1[g], TableHeadings -> {{"x", "y"}, {"min", "max"}}], 
  "plot range", Top]]

enter image description here

3. Inject Charting`ChartStyleInformation["BoundingBox"] into ChartElementFunction option setting:

ClearAll[prF3]
prF3 = Module[{boundingbox}, Histogram[#, ChartElementFunction -> 
 ((boundingbox = Charting`ChartStyleInformation["BoundingBox"]; 
      ChartElementData["Rectangle"][##]) &)]; boundingbox] &;

prF3[dd]

{{-2.5, 3.}, {0, 45}}

4. Use Charting`get2DPlotRange[g] and Options[g, PlotRangePadding] to compute the plot range:

The function Charting`get2DPlotRange gives padded plot range (including PlotRangePadding values):

Charting`get2DPlotRange[g]

{{-2.61, 3.11}, {-0.9, 49.5}}

The value of the option PlotRangePadding is easily obtained:

Options[g, PlotRangePadding]

{PlotRangePadding -> {{Scaled[0.02], Scaled[0.02]},{Scaled[0.02], Scaled[0.1]}}}

Given padded plot range and padding information we can solve for the value of plot range:

paddingsF = Module[{i = 1}, (-1)^(i++) # & @@@ #] & /@ 
  (PlotRangePadding /. Options[#, PlotRangePadding]) &;

prF4 = Module[{aa = Array[a, {2, 2}]},
    Chop[aa /. First@Solve[aa + (First /@ Differences /@ aa) paddingsF[#] == 
         Charting`get2DPlotRange[#], Flatten[aa], Reals]]] &;

prF4 @ g

{{-2.5, 3.}, {0, 45}}

Note: The last method works in version 9, but not in version 11.

$\endgroup$
6
  • 1
    $\begingroup$ These all fail in different ways when I use them on a Histogram with "PDF" option. Modifying prF2 to: prF2 = Through[{Min, Max}@#] & /@ Transpose[Join @@ Cases[# // ToBoxes, RectangleBox[x_, y_, ___] :> {x, y}, \[Infinity]] /. NCache[_, vals_] -> vals] &; seems to salvage that one though (lightly tested in v10.0 and 12.1). $\endgroup$ Commented Dec 1, 2020 at 2:49
  • $\begingroup$ @ChrisK, I will post an update if I find a fix that works in v12.1 $\endgroup$ Commented Dec 1, 2020 at 3:20
  • $\begingroup$ Thanks, but to clarify, that modification I made in my comment seems to work in v12.1. $\endgroup$ Commented Dec 1, 2020 at 3:25
  • $\begingroup$ Just checked on v12.1 (Wolfram Cloud); prf2 and prf3 both work for both "Count" and "PDF". (prF1 and prF4 look hopeless:(). $\endgroup$ Commented Dec 1, 2020 at 3:27
  • 1
    $\begingroup$ Both prF3[dd] (modified to add Automatic and "PDF" in the second and third arguments of Histogram) and prF2@Histogram[dd, Automatic, "PDF"] (without modification) give {{-2.5, 3.}, {0, 0.45}} . $\endgroup$ Commented Dec 1, 2020 at 3:32
3
$\begingroup$

For the PlotRange, you can use my function graphicsInformation:

SeedRandom[1];
g = Histogram[RandomVariate[NormalDistribution[0, 1], 200]]

pr = "PlotRange" /. graphicsInformation[g]

enter image description here

{{-2.61458, 3.11458}, {-0.967742, 47.4194}}

As you say, using AbsoluteOptions to obtain the Ticks doesn't work:

Ticks /. AbsoluteOptions[g]

PlotRange::prng: Value of option PlotRange -> {{-2.5,3.},{All,All}} is not All, Full, Automatic, a positive machine number, or an appropriate list of range specifications.

PlotRange::prng: Value of option PlotRange -> {{-2.5,3.},{All,All}} is not All, Full, Automatic, a positive machine number, or an appropriate list of range specifications.

PlotRange::prng: Value of option PlotRange -> {{-2.5,3.},{All,All}} is not All, Full, Automatic, a positive machine number, or an appropriate list of range specifications.

General::stop: Further output of PlotRange::prng will be suppressed during this calculation.

{Automatic, Automatic}

Base on the error message, we can fix this by inserting the PlotRange manually:

Ticks /. AbsoluteOptions[Show[g, PlotRange->pr]] //Short

{{{-2.,-2.,{0.00625,0.},{,AbsoluteThickness[0.25]}},<<27>>,{-2.6,,{0.00375,0.},{,AbsoluteThickness[0.125]}}},{<<1>>}}

$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.