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 would like to get a 3D visualization of a given matrix.

Here is a figure which may come from Mathematica. I want to plot something like it. When I use ListPlot3D or BarChart3D to plot my matrix, it does not have the style of one shown below, which is what I'm look for. How can I do a nice 3D visualization of my matrix?

visualization of a matrix

data = ( {
    {1, 2, 3},
    {5, 4, 8},
    {2, 5, 7}
   } );

data = ArrayPad[data, {0, 1}];
xTicks = {{1.5, "A"}, {2.5, "B"}, {3.5, "C"}};
yTicks = {{1.5, "X"}, {2.5, "Y"}, {3.5, "Z"}};
zTicks = {{0, "0"}, 0, {4, "4"}, {8, "8"}};

pic = ListPlot3D[data, 
  Mesh -> None, 
  InterpolationOrder -> 0, 
  ColorFunction -> "Rainbow",
  Filling -> Bottom,
  FillingStyle -> {Opacity[0.9]},
  PlotRange -> {Min[data] - 0.5, Max[data] + 0.2},
  BoxRatios -> {1, 1, 0.5},
  Ticks -> {xTicks, yTicks, zTicks},
  DataRange -> All,
  Boxed -> False,
  FaceGrids -> {Bottom, Back, Left},
  ImageSize -> 400]

this is the code that I plot a matrix using ListPlot3D. The cuboids in it are not separate from each other, and the edges of the cuboid are fuzzy.

my figure for matrix from the above code

share|improve this question
    
What code did you try, and in what way does the output "not look good?" –  Mr.Wizard Mar 16 '13 at 7:05
    
Thanks for adding the code. Now, what don't you like about it? Are you trying to reproduce the first as closely as possible, or is it more general? Do you dislike the text, or the lack of the full box frame around the plot? Put another way: define "nice." –  Mr.Wizard Mar 16 '13 at 7:22
    
Great thanks Wizard. I want to reproduce the first figure and do some improvement to it, such as the x&y ticks in the original figure do not in the middle of the bottom of the cuboid. –  cmc Mar 16 '13 at 7:30
add comment

3 Answers 3

If I have time later tonight I'll give you a graphic matching demo as I did for other users here and here.

As usual I recommend building a specific graphic from Graphics (or Graphics3D) primitives so I suggest you spend some time reading about those, e.g. Cuboid.

As a quick fix you can use BarChart3D as follows:

data = SparseArray[Tuples[{1, 4}, 2] -> 0.3, {4, 4}, 0.01];

chart = BarChart3D[data, ChartLayout -> "Grid"]

Mathematica graphics

There are many Options you can use to customize this. Please spend some time reading about those as well. Once you get comfortable with graphics primitives and the internal format of these objects you can perform manipulations on the output to further customize them.


Okay, here is a fairly close approximation:

data = SparseArray[Tuples[{1, 4}, 2] -> 0.3, {4, 4}, 0.01];
data[[2 ;; 3, 2 ;; 3]] += 0.1;
data3D = Join @@ MapIndexed[Append[#2, #] &, data, {2}];

labels = {"VV", "VH", "HV", "HH"};

bar[n_][{x_, y_, z_}] := Cuboid[{x - n, y - n, 0}, {x + n, y + n, z}]
Graphics3D[
 bar[0.25] /@ data3D,
 Axes -> True,
 LabelStyle -> {FontFamily -> "Helvetica", 19},
 Ticks -> {MapIndexed[{5 - #2[[1]], #} &, labels],
           MapIndexed[{#2[[1]], #} &, labels], 
           Automatic},
 FaceGrids -> {{-1, 0, 0}, {0, 1, 0}, {0, 0, -1}},
 BoxRatios -> {1, 1, 1},
 BoxStyle -> AbsoluteThickness[2.5],
 PlotRangePadding -> 0.25,
 ViewPoint -> 1.5 {1.77, -2.29, 1.74},
 ImageSize -> 330
]

Mathematica graphics

The original:

original

share|improve this answer
    
+1 but how do you make a cuboid have a red top and blue sides? –  cormullion Mar 16 '13 at 8:08
    
@cormullion By changing the Lighting. For example the default colors match the OP's image: Graphics3D[Cuboid[]] or in all white: Graphics3D[Cuboid[], Lighting -> "Neutral"] –  Mr.Wizard Mar 16 '13 at 8:10
    
Yes I suppose that's the only way... –  cormullion Mar 16 '13 at 8:11
    
@cormullion In newer versions there is Texture. –  Mr.Wizard Mar 16 '13 at 8:13
    
Not on a single face, though apparently –  cormullion Mar 16 '13 at 8:17
add comment
 data = ({{1, 2, 3}, {5, 4, 8}, {2, 5, 7}});
 data = ArrayPad[data, {0, 1}];
 xTicks = {{1, "A"}, {2, "B"}, {3, "C"}};
 yTicks = {{1, "X"}, {2, "Y"}, {3, "Z"}};
 zTicks = {{0, "0"}, 0, {4, "4"}, {8, "8"}};
 pltstyl = {ColorFunction -> "Rainbow", 
  PlotRange -> {Min[data] - .2, Max[data] + 0.2}, 
   BoxRatios -> {1, 1, 0.5}, Ticks -> {xTicks, yTicks, zTicks}, 
   Boxed -> False, FaceGrids -> {Bottom, Back, Left},  ImageSize -> 400};

Using BubbleChart3D with a custom ChartElementFunction:

(* transform data to a form acceptabele to BubbleChart3D:*)
bcdata =Join@@MapIndexed[Composition[Append[#, 1] &, Flatten, Reverse, List], data, {2}]; 
(* custom ChartElementFunction to produce cuboids with appropriate heights *)
ceFunc[{{xmin_, xmax_}, {ymin_, ymax_}, {zmin_, zmax_}}, v_, meta_] :=
  {Cuboid[{xmin, ymin, 0.}, {xmax, ymax, (zmax + zmin)/2}]};
BubbleChart3D[bcdata, ColorFunction -> (ColorData["Rainbow"][#3] &), 
 ChartStyle -> Opacity[.9],
 ChartElementFunction -> ceFunc, BubbleSizes -> {0.15, .15}, 
 Evaluate@pltstyl]

enter image description here

Post-processing BubbleChart3D to reshape the cuboids

BubbleChart3D[bcdata, ColorFunction -> (ColorData["Rainbow"][#3] &), 
 ChartStyle -> Opacity[.9], ChartElementFunction -> "Cube", BubbleSizes -> {0.15, .15}, 
 Evaluate@pltstyl] /. 
CuboidBox[{a_, b_, c_}, {e_, f_, g_},rest___]:>CuboidBox[{a, b, 0}, {e, f,(c + g)/2}, rest]

enter image description here

Using DiscretePlot3D with Interpolation:

(* interpolation of 3D data: *)
intF = Interpolation[Join @@ MapIndexed[Composition[Reverse, List], data, {2}]];
DiscretePlot3D[intF[i, j], {i, 1, 4}, {j, 1, 4}, 
ExtentSize -> Scaled[.75], Evaluate@pltstyl]

enter image description here

share|improve this answer
add comment

I tried to follow in the steps of the great Mr.Wizard, using cuboids, or rather polygons:

cuboid[origin_, box_List, colors_List] := 
 Module[
  {vertexList = {
     {{1, 1, 1}, {0, 1, 1}, {0, 0, 1}, {1, 0, 1}}, (* up *)
     {{1, 1, 1}, {1, 0, 1}, {1, 0, 0}, {1, 1, 0}}, (* right *)
     {{0, 1, 1}, {0, 1, 0}, {0, 0, 0}, {0, 0, 1}}, (* left *)
     {{0, 0, 1}, {0, 0, 0}, {1, 0, 0}, {1, 0, 1}}, (* front *) 
     {{1, 1, 1}, {1, 1, 0}, {0, 1, 0}, {0, 1, 1}}, (* back *)
     {{0, 0, 0}, {0, 1, 0}, {1, 1, 0}, {1, 0, 0}}} (* down *) 
   },
   (* scale *)
   vertexList = Map[Times[box, #] &, vertexList, {2}];
   (* move *)
   vertexList = Map[Plus[origin, #] &, vertexList, {2}];
   Riffle[colors, Polygon /@  vertexList]] 

Then, with some suitable data:

fullData = {{1, 1, 1}, {1, 2, 2}, {1, 3, 3}, {2, 1, 4}, 
    {2, 2, 5}, {2, 3, 6}, {3, 1, 7}, {3, 2, 8}, {3, 3, 9}};
xTicks = {{1.5, "A"}, {2.5, "B"}, {3.5, "C"}};
yTicks = {{1.5, "X"}, {2.5, "Y"}, {3.5, "Z"}};
zTicks = {{0, "0"}, 0, {4, "4"}, {8, "8"}};

Graphics3D[
 {
  cuboid[{#[[1]], #[[2]], 0}, {.5, .5, #[[3]]}, 
    {Cyan, Orange, LightGray, Purple, Gray, Gray}] & /@ fullData
  }, 
 Boxed -> True, 
 Axes -> True, 
 AxesLabel -> {x, y, z}, 
 Lighting -> {{"Ambient", White}},
 FaceGridsStyle -> Directive[Opacity[0.4], Gray],
 PlotRange -> {-2, 10},
 BoxRatios -> {1, 1, 0.7},
 Ticks -> {xTicks, yTicks, zTicks},
 FaceGrids -> {Bottom, Back, Left}

Each face has its own color.

graphic

With this sort of graphic, it's quite hard to read the heights accurately. But that's another story.

share|improve this answer
    
That was a bit of work! +1 –  Mr.Wizard Mar 18 '13 at 10:32
    
@Mr.Wizard the struggle is clearly visible... :) –  cormullion Mar 18 '13 at 10:43
add 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.