Plot of bars with height data in Mathematica - wolfram-mathematica

I have a matrix {{2, 1, 2, 2, 1}, {1, 3, 0, 1, 2}, {3, 3, 0, 3, 1}, {1, 1, 2, 1, 1}}, and I want to generate a 3d plot such as there are a total of 4*5=20 bars.
There is a bar of height 2 based at the little square (1, 1) (i.e. the square formed on the x-y plane by the points {{0,0},{0,1},{1,1},{1,0}}),
another bar of height 1 based at the little square (1,2) (i.e. the square formed on the x-y plane by the points {{0,1},{0,2},{1,2},{1,0}}),
...
another bar of height 3 based at the little square (2,2) (i.e. the square formed on the x-y plane by the points {{1,1},{2,1},{2,2},{1,2}})
...
and another bar of height 1 based at the little square (4,5) (i.e. the square formed on the x-y plane by the points {{3,4},{4,4},{4,5},{3,5}})
I cannot find an easy way to do this. Thanks a lot for your help!

What you want is BarChart3D.
Note, this function exists in two incarnations:
There is a BarChart3D in the BarCharts package. This function does what you want out of the box, but is deprecated in Mathematica 7+.
Then there's a BarChart3D in the main namespace (Mathematica 7+ only), which can do what you want as well, but needs to be passed the option ChartStyle -> "Grid" to display the result you want.
Here is some example code for both of these:
Mathematica 6 and prior
<<BarCharts`;
data = {{2, 1, 2, 2, 1}, {1, 3, 0, 1, 2}, {3, 3, 0, 3, 1}, {1, 1, 2, 1, 1}};
BarChart3D[data]
Mathematica 7 and later
data = {{2, 1, 2, 2, 1}, {1, 3, 0, 1, 2}, {3, 3, 0, 3, 1}, {1, 1, 2, 1, 1}};
BarChart3D[data, ChartLayout -> "Grid"]

data = {{2,1,2,2,1}, {1,3,0,1,2}, {3,3,0,3,1}, {1,1,2,1,1}};
BarChart3D[data, ChartLayout -> "Grid", BarSpacing -> 0]
Edit
Updating after wiki-specifying the question :
BarChart3D[data, ChartLayout -> "Grid", BarSpacing -> {0, 0},
LabelingFunction -> (Row[{#1, Reverse[#2 - 1], Reverse[#2]}] &),
AxesLabel -> {"x", "y", "z"}]
Here the both x and y-spacings vanish. Setting the cursor on a given bar you get z{x_min,y_min}{x_max,y_max}, on the top-red i.e. : 2{4,1}{5,2}

Related

Extending ListPointPlot3D with a 3rd variable?

I am trying to extend a function like this: (a 4x4 square)
ListPointPlot3D[Table[{x, y, 0}, {x, 0, 4, 1}, {y, 0, 4, 1}]]
into something like this: (a 4x4x4 cube)
ListPointPlot3D[Table[{x, y, z}, {x, 0, 4, 1}, {y, 0, 4, 1}, {z, 0, 4, 1}]]
by adding a 3rd dimension.
However, the dimensions of the latter seem to be incorrect. It seems to form a 2x2 matrix of 3d points rather than a list.
Any ideas how to fix this?
If you look a bit more closely you'll see that the expression
Table[{x, y, z}, {x, 0, 4, 1}, {y, 0, 4, 1}, {z, 0, 4, 1}]
returns a structure with 5x5x5 triplets. That is exactly what the expression is supposed to return. You can see this if you apply the Dimensions[] function to the returned structure.
There are several ways to turn the table into a list of 125 triplets, one is to use Flatten like this
Flatten[Table[{x, y, z}, {x, 0, 4, 1}, {y, 0, 4, 1}, {z, 0, 4, 1}], 2]
Or you could simply generate your list of triplets directly; for your example one alternative would be
Tuples[Range[0, 4], 3]

Generating Manipulate 'sliders' on the fly

Mathematica's Manipulate function takes as its final arguments separate lists of the parameters you want sliders for along with their value ranges. But why not a list of lists?
This way I could I easily generate all the sliders for this big list of transformation rules that I have, e.g.:
parms = {a -> 2, b -> 4, c -> 5};
Table[{{parms[[i]][[1]], parms[[i]][[2]]}, 0, 10}, {i, 1,Length[parms]}]
{{{a, 2}, 0, 10}, {{b, 4}, 0, 10}, {{c, 5}, 0, 10}}
What I would like to have, however, is:
{{a, 2}, 0, 10}, {{b, 4}, 0, 10}, {{c, 5}, 0, 10}
This I'm copy pasting now between cells, which is rather messy. I'm sure there's a better way to do this. Please help, thanks!
Please see this and this on similar questions.
What you need is Sequence## to get the list of lists to be treated as your desired output when used as input.
Perhaps something like:
ClearAll[a, b, c];
parms = {a -> 2, b -> 4, c -> 5};
With[{values = Table[parms[[i]][[1]], {i, 1, Length[parms]}],
controls = Sequence ##
Table[{{parms[[i]][[1]], parms[[i]][[2]],
Style[ToString[parms[[i]][[1]]], Red, Bold]}, 0, 10}, {i, 1,
Length[parms]}]},
Manipulate[values, controls]]
which gives

How to calculate a matrix formed by vector in Mathematica

I need to obtain a matrix vvT formed by a column vector v. i.e. the column vector v matrix times its transpose.
I found Mathematica doesn't support column vector. Please help.
Does this do what you want?
v = List /# Range#5;
vT = Transpose[v];
vvT = v.vT;
v // MatrixForm
vT // MatrixForm
vvT // MatrixForm
To get {1, 2, 3, 4, 5} into {{1}, {2}, {3}, {4}, {5}} you can use any of:
List /# {1, 2, 3, 4, 5}
{ {1, 2, 3, 4, 5} }\[Transpose]
Partition[{1, 2, 3, 4, 5}, 1]
You may find one of these more convenient than the others. Usually on long lists you will find Partition to be the fastest.
Also, your specific operation can be done in different ways:
x = {1, 2, 3, 4, 5};
Outer[Times, x, x]
Syntactically shortest:

Effect of change in Viewpoint->{x,y,z} on the size of graphic objects is not what I expected. How to fix?

If you run the following code snippet:
Manipulate[
Graphics3D[
{Cuboid[{{-1, -1, -1}, {1, 1, 1}}], Sphere[{5, 5, 5}, 1]},
ViewPoint -> {1, 1, a}, AxesOrigin -> {0,0,0}
],
{a, 1, 100}
]
and move the viewpoint from (1,1,1) to (1,1,100) with the slider you will see that after a while the objects remain fixed in size.
Questions.
1. When I move the viewpoint further away from the scene I want the objects to become smaller. How should this be done in Mathematica?
( EDIT: )
2. What is the position of the 'camera' in relation to Viewpoint?
See ViewAngle. Under "More Information", note that the default setting ViewAngle -> Automatic is effectively equivalent to ViewAngle -> All when you zoom far enough out.
You just need to add an explicit setting for ViewAngle:
Manipulate[
Graphics3D[{Cuboid[{{-1, -1, -1}, {1, 1, 1}}], Sphere[{5, 5, 5}, 1]},
ViewPoint -> {1, 1, a}, AxesOrigin -> {0, 0, 0},
ViewAngle -> 35 Degree], {a, 1, 100}]
As far as I know, the camera viewpoint really coincides with the position given by ViewPoint. Because Mathematica scales the result to fit in about the same image you don't see much changes but they are there. The perspective changes considerably. Try, for instance, to move away from a semi-transparant square and you'll see that the farther you go, the more the projection becomes an orthogonal projection:
If you want to scale your image according to distance you can use ImageSize. SphericalRegion is good to stabilize the image.
Manipulate[
vp = {1, 1, a};
Graphics3D[{Cuboid[{{-1, -1, -1}, {1, 1, 1}}], Sphere[{5, 5, 5}, 1]},
ViewPoint -> vp,
AxesOrigin -> {0, 0, 0},
SphericalRegion -> True,
ImageSize -> 500/Norm[vp]],
{a, 1, 100}
]
[animation made with some ImagePadding to keep object in the center. I stopped the animation at a = 10, the image gets pretty small after that]

Mathematica: Removing graphics primitives

Given that g is a graphics object with primitives such as Lines and Polygons, how do you remove some of them? To add more primitives to an existing graphics object we can use Show, for instance: Show[g, g2] where g2 is another graphics object with other primitives. But how do you remove unwanted primitive objects? Take a look at the following
ListPlot3D[{{0, 0, 1}, {1, 0, 0}, {0, 1, 0}, {1, 1, 0}}, Mesh -> {1, 1}]
Now, for the input form:
InputForm[
ListPlot3D[{{0, 0, 1}, {1, 0, 0}, {0, 1, 0}, {1, 1, 0}}, Mesh -> {1, 1}]
]
To create a wire frame from this object all we have to do is remove the polygons. As an extra we can also remove the vertex normals since they don't contribute to the wireframe.
Notice that to make a wireframe we can simply set PlotStyle -> None as an option in ListPlot3D. This gets rid of the Polygons but doesn't remove the VertexNormals.
To clarify the question. Given that
g = ListPlot3D[{{0, 0, 1}, {1, 0, 0}, {0, 1, 0}, {1, 1, 0}}, Mesh -> {1, 1}]
How do you remove some of the of the graphics primitives from g and how do you remove some of the options, i.e. VertexNormals? Note: option VertexNormals is an option of GraphicsComplex.
If this is not possible then maybe the next question would be, how do you obtain the data used to generate g to generate a new graphics object with some of the data obtained from g.
One way is to use transformation rules. Given your
im = ListPlot3D[{{0, 0, 1}, {1, 0, 0}, {0, 1, 0}, {1, 1, 0}}, Mesh -> {1, 1}]
You can do
newim = im /. {_Polygon :> Sequence[], (VertexNormals -> _) :> Sequence[]}
or, more compactly using Alternatives:
newim = im /. _Polygon | (VertexNormals -> _) :> Sequence[]
You could also use DeleteCases to get a similar effect:
newim = DeleteCases[im, (_Polygon | (VertexNormals -> _)), Infinity]

Resources