2
$\begingroup$

I have some (discrete) data of the type $\{x_i,y_i,z_i\}$

data={{4, 4, 0.6570}, {6, 4, 0.8240}, {8, 4, 0.8930}, {10, 4, 0.9330},{4,6, 0.2780}, {6,6,0.5660}, {8, 6, 0.7460}, {10, 6, 0.8320}, {4, 8,0}, {6, 8, 0.2620}, {8, 8, 0.5100}, {10, 8, 0.6100}, {4,10, 0}, {6,10, 0.04900}, {8, 10, 0.2370}, {10, 10, 0.3940}}

and I'm looking to make a 3D histogram out of this, with rectangles of height $z_i$ and square base located in the plane at position $x_i,y_i$. This used to be possible using ``GeneralizedBarChart3D" but this has been replaced by RectangleChart3D and I can't make it work.

The best I can do right now is

ListPointPlot3D[data, Filling -> Bottom]

which produces something like

enter image description here

where the points are correctly located and at the correct height, but I want to have a rectangle (with a square base of width 1) of the correct height rather than a point.

Any help would be appreciated.

$\endgroup$
  • $\begingroup$ Histogram3D[Function[y, Table[{y[[1]], y[[2]]}, y[[3]]]] /@ (Function[x, {x[[1]], x[[2]], x[[3]]*10000}] /@ data)] $\endgroup$ – Harshal Gajjar Jun 26 at 19:17
  • $\begingroup$ You could use ListPlot3D with a 0 interpolation order: ListPlot3D[data, Filling -> Bottom, InterpolationOrder -> 0] $\endgroup$ – Carl Lange Jun 26 at 19:23
  • $\begingroup$ To account for the data point {4, 4, 0.6570}, I add the point {4,4} 0.6570*10000 = 6570 times (into a temporary array). Repeat this for all points and then plot the histogram(3D) of this temporary array (containing {4,4} repeated 6570 times). $\endgroup$ – Harshal Gajjar Jun 26 at 19:41
  • 1
    $\begingroup$ Building on @Carl's comment ListPlot3D[data, Filling -> Bottom, InterpolationOrder -> 0, PlotRange -> {{3, 11}, {3, 11}}, ColorFunction -> "SouthwestColors", Mesh -> None] $\endgroup$ – Harshal Gajjar Jun 26 at 19:50
  • 1
    $\begingroup$ @HarshalGajjar Thanks... Somehow the functionality "GeneralizedBarChart3D" was not really replaced. $\endgroup$ – ZeroTheHero Jun 26 at 20:26
2
$\begingroup$

Transform data into a WeightedData object and use it with Histogram3D:

wd = WeightedData[data[[All, ;; 2]], data[[All, -1]]]; 

Histogram3D[wd, {1}, ColorFunction -> "Rainbow"]

enter image description here

Change the bin specification to {2}:

Histogram3D[wd, {2}, ColorFunction -> "Rainbow"]

enter image description here

To show data elements with zero weight replace 0s in the third column of data with a small number (say, 10^-6):

wd2 = WeightedData[data[[All, ;; 2]], data[[All, -1]] /. 0 -> 10^-6]; 

Histogram3D[wd2, {1}, ColorFunction -> "Rainbow"]

enter image description here

| improve this answer | |
$\endgroup$
3
$\begingroup$

You don't have a histogram but really a 3D bar chart as the heights don't sum to 1 or a total sample size. But with your particular dataset where all combinations of values for each dimension (going from 4 to 10 in steps of 2) are available, one can easily use DiscretePlot3D:

DiscretePlot3D[data[[4 (i/2 - 2) + j/2 - 1, 3]], {i, 4, 10, 2}, {j, 4, 10, 2}, 
  ExtentSize -> Full, FillingStyle -> Opacity[1]]

3D bar chart

An alternative approach that avoids the "gymnastics" you mention is to use a sparse array:

data = {{4, 4, 0.6570}, {6, 4, 0.8240}, {8, 4, 0.8930}, {10, 4, 0.9330}, 
  {4, 6, 0.2780}, {6, 6, 0.5660}, {8, 6, 0.7460}, {10, 6, 0.8320}, {4, 8, 0},
  {6, 8, 0.2620}, {8, 8, 0.5100}, {10, 8, 0.6100}, {4, 10, 0}, {6, 10, 0.04900}, 
  {8, 10, 0.2370}, {10, 10, 0.3940}}
sa = SparseArray[{#[[1]], #[[2]]} -> #[[3]] & /@ data]
DiscretePlot3D[sa[[i, j]], {i, 4, 10, 2}, {j, 4, 10, 2}, 
  ExtentSize -> Full, FillingStyle -> Opacity[1]]

3D bar plot alternative approach with a sparse array

| improve this answer | |
$\endgroup$
  • $\begingroup$ Nice. You have to do quite a bit of gymnastics to generate the proper format for the plot... $\endgroup$ – ZeroTheHero Jun 26 at 21:53
  • 2
    $\begingroup$ Maybe you need more exercise. ;) $\endgroup$ – JimB Jun 26 at 23:36

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.