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$
5
  • 3
    $\begingroup$ You could try ImageLevels to get the data, then plot manually. $\endgroup$
    – Szabolcs
    Jan 16, 2016 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, 2016 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, 2016 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, 2016 at 10:39
  • $\begingroup$ I tried your first solution and it works perfect. Thank you. $\endgroup$
    – mrz
    Jan 18, 2016 at 13:03

1 Answer 1

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 and acknowledge that you have read and understand our privacy policy and code of conduct.

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