3
$\begingroup$

ImageHistogram is much faster than Histogram with ImageData.

The only problem: I cannot find out how to make the y axis logarithmic. Is this possible?

I am using Mathematica 10.3.1.

$\endgroup$
  • 3
    $\begingroup$ You could try ImageLevels to get the data, then plot manually. $\endgroup$ – Szabolcs Jan 16 '16 at 21:06
  • $\begingroup$ Interpreting a logarithmic histogram y-axis is problematic at best. What about transforming the data with a log or square root? That leaves the resulting histogram comparable among different sets of data and hopefully shows desired features of the data. $\endgroup$ – JimB Jan 16 '16 at 21:11
  • $\begingroup$ To Szabolcs: Very helpful your info. I used "ListLogPlot [ImageLevels[image], InterpolationOrder -> 0, Joined -> True]". This works fine and is relatively fast. The only problem is that missing image levels do not appear in ListLogPlot. So empty gaps occur for those data, which looks different than in ImageHistogram or Histogram and is not really nice for presentation. Do you have an idea if ListLogPlot can produce plots that look as Histograms? See for example the histogram plot i.stack.imgur.com/X5dkA.png $\endgroup$ – mrz Jan 16 '16 at 23:03
  • 1
    $\begingroup$ Maybe something like hist = ImageLevels@ ColorConvert[ExampleData[{"TestImage", "Lena"}], "Grayscale"]; Histogram[WeightedData @@ Transpose[hist], Automatic, {"Log", "PDF"}] or maybe BarChart with ScalingFunctions $\endgroup$ – Szabolcs Jan 17 '16 at 10:39
  • $\begingroup$ I tried your first solution and it works perfect. Thank you. $\endgroup$ – mrz Jan 18 '16 at 13:03
6
$\begingroup$

Here is an answer from the Wolfram Technical Support:

Mathematica does not currently allow for an option for a logarithmic scale in ImageHistogram. However, taking apart the underlying structure, it is possible to rescale the data. The underlying structure is a GraphicsComplex, such that the following code should get you started on a workaround for your interests:

LogImageHistogram[input_Image, base_?NumericQ /; base >= 2] :=
 Module[
  {
   imh = ImageHistogram[input], logdata
   },
  logdata = MapAt[
     Log[#]/Log[base] &, 
     First@Cases[imh, GraphicsComplex[x_, y_] :> x, Infinity], {All, 2}
     ] /. Indeterminate -> -1;

  (
    imh /. GraphicsComplex[x_, y_] :> GraphicsComplex[logdata, y]
    ) /.
   {
    Rule[FrameTicks, x_] :> Rule
      [
      FrameTicks, {
       {
        {#, base^#} & /@ Range[1, 10] // N, None
        }, {Automatic, Automatic}
       }
      ],
    Rule[PlotRange, x_] :> Rule[PlotRange, {0, Max[logdata]}]
    }
  ]

This function takes two arguments,

1) the input image and

2) the logarithmic base with which to scale the y-axis.

This function isn't perfect because I only generate 10 tick marks, but these things can be adjusted by hand.

Also, because the GraphicsComplex contains some zeroes for the y-coordinates, I've artificially set these to -1 because the Log[0] is Indeterminate. You won't see these because the PlotRange starts at 0.

Show
 [
  LogImageHistogram[image, #], 
  BaseStyle -> {FontFamily -> "Calibri", FontSize -> 20}, 
  ImageSize -> 800
 ] & /@ {10, 2}

gives:

enter image description here

$\endgroup$

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.