Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I am using a Histogram3D plot to view the correlation of the R & G of an RGB image. Naturally, I want the bins to have a color corresponding to their $x$, $y$ (R,G) position on the chart.

Unfortunately, ColorFunction for Histogram3D only supplies one argument, height, not $x$ or $y$ position.

Is there a way to color each bin based on its $x$ and $y$ position within the histogram? (i.e. RGBColor[x,y,0])

Here is how I am generating my (uncolored) histogram:

    Histogram3D[Transpose[{
                           Flatten[ImageData[jpeg][[All,All,1]]]
                          ,Flatten[ImageData[jpeg][[All,All,2]]]
                           }]]
share|improve this question
    
Yes, exactly. I also want to make two other plots: R,B: RGBColor[x,0,y] and B,Y: RGBColor[0,x,y] –  Perfect Tommy Sep 16 '13 at 23:01
    
I'm not sure what that should show. For example RGBColor[1, 1, 0] is Yellow, but it doesn't mean it was Yellow in the image since you are not counting Blue. –  Kuba Sep 16 '13 at 23:04
    
Yes, I am aware. I would like to display the color value without the Blue Counted. –  Perfect Tommy Sep 16 '13 at 23:06
    
You may be interested in my edit. I've also made your code more compact. –  Kuba Sep 17 '13 at 6:13
add comment

2 Answers

up vote 11 down vote accepted

Thanks to ybeltukov I realised that post-processing way is not so bulletproof. Let's write a little bit longer solution to take control.

ChartElementFunction, is a handy way to deal with this (only a little bit adapted example for documentation):

f[{{xmin_, xmax_}, {ymin_, ymax_}, {zmin_, zmax_}}, ___] := {
         RGBColor[Mean[{xmin, xmax}], Mean[{ymin, ymax}], 0], 
         Cuboid[{xmin, ymin, zmin}, {xmax, ymax, zmax}]}

And it works for small images too:

jpeg = ImageResize[ExampleData[{"TestImage", "Mandrill"}], 5]

hist = Histogram3D[
                   Flatten[ImageData[jpeg][[;; , ;; , {1, 2}]], 1],
                   ChartElementFunction -> f]

(I have changed a little bit your code to make it more compact).

enter image description here


Edit All of the graphs you asked for. I had to modify f to make it more useful:

f[{x_, y_, z_}, ___, OptionsPattern[Irrelevant -> 1]] := {
               RGBColor @@ Insert[{Mean@x, Mean@y}, 0, OptionValue[Irrelevant]], 
               Cuboid @@ Transpose[{x, y, z}]}


jpeg = ImageResize[ExampleData[{"TestImage", "Mandrill"}], 100]

Histogram3D[Flatten[ImageData[jpeg][[;; , ;; , #]], 1], PlotLabel -> #2,
            ChartElementFunction -> (f[##, Irrelevant -> "x"] & /. "x" -> #3)
           ] & @@@ {{{1, 2}, "R - G", 3}, 
                    {{1, 3}, "R - B", 2}, 
                    {{2, 3}, "G - B", 1}} // GraphicsRow[#, ImageSize -> 1000] &

enter image description here


"Post-processing" way, works automatically only for larger images, for small, take a look @ybeltukov solution.

ChartElements are Cuboid s. r1 and r2 are coordinates of oposite vertices. Just reffer the color to them as you like. r2 = {x2, y2, z2} so you can involve height too.

To achieve what you've described in comments:

hist /. Cuboid[r1_, r2_] :> {RGBColor[##, 0] & @@ Most@(Mean /@ Transpose[{r1, r2}])
                             , Cuboid[r1, r2]}

enter image description here

share|improve this answer
    
@PerfectTommy does my edit fits your needs? –  Kuba Sep 16 '13 at 23:10
1  
If you want this to work on small images add the option PerformanceGoal -> "Speed" to Histogram3D. –  Mr.Wizard Sep 17 '13 at 0:29
1  
@Mr.Wizard Thank's for the remark. ChartElementFunction has this advantage that it still creates tooltips for small images :) –  Kuba Sep 17 '13 at 6:59
    
@Kuba I ended up using the "post-processing" method and it worked wonderfully. Thanks! –  Perfect Tommy Sep 20 '13 at 19:17
    
@PerfectTommy I'm glad it helps :) good luck! –  Kuba Sep 20 '13 at 19:19
add comment

Solution of Kuba works fine only for large images when bars on Histogram3D are not dynamic objects with tooltips. I provide more general solution

hist /. (h_ /; h === CuboidBox || h === Cuboid)[r1_, r2_] :> 
With[{col = Append[Most[r1 + r2]/2, 0]}, {RGBColor[col], h[r1, r2]} /; True])

For small data set there is CuboidBox instead of Cuboid. Moreover CuboidBox is in held expression so I use Trott-Strzebonski in-place evaluation technique.

Examples

  1. Small image

    jpeg = Image[RandomReal[1, {8, 12, 3}]]
    hist = Histogram3D[
       Transpose[{Flatten[ImageData[jpeg][[All, All, 1]]], 
         Flatten[ImageData[jpeg][[All, All, 2]]]}]];
    hist /. (h_ /; h === CuboidBox || h === Cuboid)[r1_, r2_] :> 
      With[{col = Append[Most[r1 + r2]/2, 0]}, {RGBColor[col], 
         h[r1, r2]} /; True]
    

    enter image description here

  2. Large image

    jpeg = Import["ExampleData/lena.tif"]
    hist = Histogram3D[
       Transpose[{Flatten[ImageData[jpeg][[All, All, 1]]], 
         Flatten[ImageData[jpeg][[All, All, 2]]]}]];
    hist /. (h_ /; h === CuboidBox || h === Cuboid)[r1_, r2_] :> 
      With[{col = Append[Most[r1 + r2]/2, 0]}, {RGBColor[col], 
         h[r1, r2]} /; True]
    

    enter image description here

share|improve this answer
    
One can add the option PerformanceGoal -> "Speed" to Histogram3D to get the "large image" behavior on small data as well. –  Mr.Wizard Sep 17 '13 at 0:30
    
@Mr.Wizard Thanks! I searched this option to no avail. –  ybeltukov Sep 17 '13 at 0:32
2  
Without help from others (this site) or an almost pathological inclination for experimentation I don't know how one is to learn of such things. I'm glad I could pass this information along. –  Mr.Wizard Sep 17 '13 at 0:50
    
@ybeltukov Good catch. I must admint I have not thought about this. Could you pleaste tell me why haven't you started to participate earlier in answering on this site? Looking on your answers I feel like we 'lost' a lot :) –  Kuba Sep 17 '13 at 5:08
    
p.s. Ok, I edited my post so it works with small images too :) –  Kuba Sep 17 '13 at 6:14
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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