4
$\begingroup$

I have a SmoothDensityHistogram plot:

plot = Show[SmoothDensityHistogram[data,
   PlotRange -> {{0, 200}, {0, 200}}, Frame -> False], 
   PlotRangePadding -> 0]

FPS

which I would like to export to an indexed data file where each pixel is a number. How could I make it?

Thank you very much

$\endgroup$
6
  • $\begingroup$ ImageData? $\endgroup$ Sep 12 '17 at 10:28
  • $\begingroup$ @aardvark2012 Thanks. ImageData gives the three channel values of each pixel. but if I want to represent the image with only an array of values, and to reproduce the image select a colormap, how can I do it? $\endgroup$ Sep 12 '17 at 10:45
  • $\begingroup$ From the documentation, SmoothDensityHistogram "... generates colorized grayscale output of the PDF...", which may mean that the lightness of the colour corresponds to the value you want. If that's the case, you could get that value by some RBG colour formula, or with ImageData[ColorConvert[image, "LAB"]][[All, All, 1]] (which basically gives you the lightness components of all the pixels, ignoring hue and chroma). $\endgroup$ Sep 12 '17 at 10:59
  • 1
    $\begingroup$ Using SmoothKernelDistribution[data] /@ {"InterpolationPoints", "PDFValues"} you can get the data needed to reconstruct the numbers underlying SmoothDensityHistogram. $\endgroup$
    – kglr
    Sep 12 '17 at 11:27
  • 2
    $\begingroup$ Documentation >> SmoothDensityHistogram: SmoothDensityHistogram effectively plots the distribution function of SmoothKernelDistribution $\endgroup$
    – kglr
    Sep 12 '17 at 11:35
5
$\begingroup$

Use SmoothKernelDistribution as, because as mentioned in Details section in docs, it is what is used for SmoothDensityHistogram:

R = 1.7;
SeedRandom[4];
data = RandomVariate[BinormalDistribution[.5], 10];
skd = SmoothKernelDistribution[data]

and because you can sample it as a "matrix" raster this distribution at a desirable scale:

sample = Table[PDF[skd, {x, y}], {y, -R, R, scale}, {x, -R, R, scale}];

-- that's the pixels you need as I understand it. In Mathematica you can see them as

ArrayPlot[sample, ColorFunction -> "SolarColors", DataReversed -> True]

enter image description here

and export as for example

Export["sample.csv", sample]

SmoothDensityHistogram is not ideal for this as it formulates as Graphics object, in terms of polygons (that you could also extract as InputForm[fig] if needed):

fig = SmoothDensityHistogram[data,
    Mesh -> All,
    Epilog -> {Blue, PointSize[.02], Point[data]},
    ColorFunction -> "SolarColors", PlotRange -> {{-R, R}, {-R, R}}]

enter image description here

$\endgroup$
2
  • $\begingroup$ Is what I pretend to make, and it works. I would also ask you if it would be possible to do the same but getting an array of Intensity or Count values as DensityHistogram can produce? $\endgroup$ Sep 12 '17 at 12:31
  • $\begingroup$ Is there a way to make the same but using DensityHistobram[] with option Count? Regards $\endgroup$ Sep 12 '17 at 13:39
3
$\begingroup$

Working from

image = your image saved as a jpeg

It's colour space (ImageColorSpace[image]) is RGB, so we'll want to convert to LAB:

id = ImageData[ColorConvert[image, "LAB"]][[All, All, 1]];

Which gives us an array of values. Plotting them using ArrayPlot:

ArrayPlot[1 - id]

enter image description here

So the data is still there, but I really have no idea how the lightness of the ColorFunction for SmoothDensityHistogram scales with the PDF, so I wouldn't pin too much on the accuracy of the numbers in id with respect to that PDF.

$\endgroup$
3
$\begingroup$

Using SmoothKernelDistribution[data] /@ {"InterpolationPoints", "PDFValues"} you can get the data needed to reconstruct the numbers underlying SmoothDensityHistogram.

Documentation >> SmoothDensityHistogram:

SmoothDensityHistogram effectively plots the distribution function of SmoothKernelDistribution.

SeedRandom[1]
data = RandomVariate[BinormalDistribution[.5], 10];

{intpoints, values} = SmoothKernelDistribution[data] /@ 
   {"InterpolationPoints", "PDFValues"};
points = Tuples[intpoints];
data3D = Append @@@ Thread[{points, values}];
valuesdata = Transpose@Partition[values, Length[intpoints[[1]]]];

You can Export valuesdata or data3D which contains the set of 3D interpolation points and pdf values {x, y, pdfvalue} that underly SmoothDensityHistogram.

Row[Prepend[ListDensityPlot[#, PlotRange -> All, ImageSize -> 300, 
     PlotLabel -> Style["ListDensityPlot - " <> #2, 16, "Panel"]] & @@@ 
    {{data3D, "data3D"}, {valuesdata, "valuesdata"}}, 
  SmoothDensityHistogram[data, PlotRange -> All, ImageSize -> 300, 
   PlotLabel -> Style["SmoothDensityHistogram", 16, "Panel"]]]]

enter image description here

Update: Is there a way to export the Count or Intensity values plotted with a DensityHistogram ?

You can use

{bins, counts} = HistogramList[data, Automatic, "Count"]

to get the array of counts, and

intensities = HistogramList[data, List /@ bins, "Intensity"][[2]]

to get the array of intensities for the same bins.

SeedRandom[1]
data = RandomVariate[BinormalDistribution[.5], 500];

Using "Count" or counts& as the third argument of DensityHistogram gives the same output:

{bins, counts} = HistogramList[data, Automatic, "Count"];
Row[{DensityHistogram[data, Automatic, "Count", ImageSize -> 300],  
   DensityHistogram[data, Automatic, counts&, ImageSize -> 300]}]

enter image description here

Similarly, using "Intensity" or intensitites& as the third argument of DensityHistogram gives the same output:

intensities = HistogramList[data, List /@ bins, "Intensity"][[2]];
Row[{DensityHistogram[data, List /@ bins, "Intensity", ImageSize ->300],
  DensityHistogram[data, List /@ bins, intensities &, ImageSize -> 300]}]

enter image description here

$\endgroup$
7
  • $\begingroup$ Thank you. Instead of pdfvalues, Is there a way to export the Count or Intensity values plotted with a DensityHistogram ? (instead SmoothDensityHistogram). $\endgroup$ Sep 12 '17 at 13:37
  • $\begingroup$ For DensityHistogram you can get the array of counts using heights = HistogramList[data, Automatic, "Count"][[2]]. Not sure how to get Intensity. $\endgroup$
    – kglr
    Sep 12 '17 at 14:02
  • $\begingroup$ In version 11, HistogramList[data, Automatic, "Intensity"][[2]] works. $\endgroup$
    – kglr
    Sep 12 '17 at 14:10
  • $\begingroup$ @user1993416, please see the update. $\endgroup$
    – kglr
    Sep 12 '17 at 14:31
  • $\begingroup$ @klgr Thank you very much. I have tested with my image which has range 200x200 and extracting Counts and Intensities, and If I want to plot these arrays with ArrayPlot I get a different range of values which depend on bin value I assign. How can I keep the original plot xy ranges? $\endgroup$ Sep 12 '17 at 14:43

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.