Matlab draw 3D stacked figure use bar3() for multiple variables [duplicate] - matlab

I have a matrix, A, that contains 50 rows and 4 columns, and the entries are filled with integers. My interest is to construct a stacked 3D bar plot from this data. However, using bar3(A,'stacked') creates a row of 50 bars, whereas I want the bars to be plotted at the coordinates of a grid of size 5 (vertical) x 10 (horizontal). So the first bar in the row would be at location (1,1), second bar at (1,2), 11th bar at (2,1) and so on until the 50th bar which would be at (5,10). I can't seem to find a way to do this in Matlab, is this possible at all?
Thank you in advance!

I agree with #cris, there are better ways to represent your data. However, something like this would work if you still want to do use a 3D bar plot:
figure
hold on
for i = 1:5
Ai = A(10*(i-1)+1:10*i,:);
h = bar3(1:10,Ai,'stacked');
for ih = 1 :length(h)
x = get(h(ih), 'Xdata');
set(h(ih), 'Xdata', x+i-1);
end
end
view(3)

Related

making a single stacked bar with colors from each stack depending on the distribution frequency

I have a vector of the size 10000x1, which I reduced to 4400x1. I want to make a stacked bar with the single entries of this vector. Each segment of the stacked bar should be colored depending on the distribution frequency. For example: if a value is represented 10 times, it should almost be black. if its only 1, it should be light grey.
1st problem: When I use a small vector, I get a stacked bar. If I use the one I need to I get multiple bars instead of one stacked bar.
2nd problem: How can I make the bar use a gray scale to color them?
I tried to transpose my vector to 1x4400 which didn't change anything.
I used bar(data,'stacked') which works for the small vector (at least I get a stacked bar. To get a single bar I used:
test = [1 2 3 4 5 1 2 3];
bar([test; nan(size(test))],'stacked');
size of data : 4400x1
bar([data; nan(size(data))],'stacked');
When I enter your first example, with an 1x8 matrix:
test = [1 2 3 4 5 1 2 3];
bar([test; nan(size(test))],'stacked');
I see the same plot you see. Then I transpose test to make it an 8x1 matrix:
test = test.';
bar([test; nan(size(test))],'stacked');
and I see something similar to your second plot:
Note how the NaNs cause the right half of the x-axis to have no bars.
Thus, to get stacked bars you need to have a row vector. However, your data is a column vector, a 4400x1 matrix. data = data.' will change that.
Nonetheless, it is likely that MATLAB is not able to make a stacked bar plot with 4400 elements. I'm trying this out on MATLAB Online, and I've been waiting for several minutes and still don't have a plot. In any case, there is no way you would become any wiser with such a plot. Don't do it!
Regarding your second question: you can change the plot color order to gray:
set(gca,'colororder',flipud(gray(256)))
However, the stacked bars are not colored according to their value, they just use the colors of the list in turn.
A better solution would be to plot your data as an image:
test = [1 2 3 4 5 1 2 3];
imagesc(test.')
colormap(flipud(gray(255)))
set(gca,'xlim',[0,2],'xtick',1)
[I just realized you might want to straighten the y-axis, imagesc inverts it. Simply: set(gca,'ydir','normal').]

How can I plot a meshgrid in Matlab with empty gridsquares (i.e. showing the gridlines) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I am using meshgrid to create matrices of coordinates to plot model output within gridded data of Europe.The dataset is 106 x 103 and everywhere there is no data, the value is set to NaN.
[meshlat,meshlon]=meshgrid(rlat,rlon);
surf(meshlon,meshlat,data(:,:,1)),'linestyle','none';view(2);
But I actually want all the grid squares that don't have output to be plotted too (so the extra ones that are in this map, comprising Scandinavia..but I want them to be white):
I'm thinking that I may need to create a third matrix the same size as the meshlat and meshlon and fill it with a number that would correspond to the colour white...plot it, then type 'hold', and plot my map on top? I'm not sure how to specify the white colour though? Or is there another way of doing it?
Here is a simplified version of the problem:
data = magic(4);
data(1,2) = nan;
x = [1,2,3,4];
lat = repmat(x,4,1);
lon = lat';
surf(lon,lat,data);view(2);
You can see the blank space on the left..In this example, I would like to see extra grid lines where the squares would be (if there were no nans in the dataset)
When I tried #Hoki's suggestion, I ended up with grid squares around every 'cell' in the matrix...whether it was filled with a number or a NaN (below) which is not what I originally needed. I wanted just the land masses (that have real numbers, not NaNs to have a gridline around them):
By using the full dataset (in the first image), I plotted the outline of the gridsquares for the landmasses using:
surf(meshlon,meshlat,fulldata(:,:,1),'FaceColor','none','EdgeColor','k');view(2);
Then I plotted my 'coloured' grid squares over that original dataset:
hold on;
surf(meshlon,meshlat,data(:,:,1)),'linestyle','none';view(2);
Using the simplified example below, the code is:
data = magic(4);
datafull=data;
data(1,2) = nan;
x = [1,2,3,4];
lat = repmat(x,4,1);
lon = lat';
surf(lon,lat,datafull,'FaceColor','none','EdgeColor','k');view(2);
hold on
surf(lon,lat,data);view(2);
There are several ways to achieve the result you want. The "cleaner" and less memory hungry way is unfortunately quite more complex than the simple workaround.
Method 1 (not recommended, and not detailed ...)
You need to create a special colormap with a "white" color at one end (min or max), making sure that the value that will map to this color are not in your data.
Before you plot your data, for all the pixels for Scandinavia (or any pixel which doesn't have a value but where you want to see your grid) replace the NaN by the value which will map to the white in the colormap.
As you can see, this method will force you to re-evaluate your colormap for each new dataset, so not very flexible.
Method 2 (Recommended, more generic ...)
Just create an empty 'grid' exactly how you want it, then display it on top of your surface plot. This grid will be transparent so it can be used on top of any dataset.
For your example:
%% Your example
data = magic(4);
data(1,2) = nan;
x = [1,2,3,4];
lat = repmat(x,4,1);
lon = lat';
surf(lon,lat,data);view(2);
%% The overlay grid:
% Create a grid the same size of the data. We set the Z value to the max of
% the original data set to make sure the grid will be "on top" of the
% surface plot when view from above.
datagrid = ones(size(data))*max(data(:)) ;
% plot the grid on top of the previous surface plot
hold on
hm = mesh(lon,lat,datagrid,'FaceColor','none','EdgeColor','k') ;
This is what you'll get. The second figure on the right is the same with a different view so you understand what is going on on the Z dimension.
With a reference grid like that, you can overlay it on any of your dataset, regardless of which areas have been blanked/nullified.

matlab heatmap plot changing axis directions

I have a function f(v,z) and z = [0:0.01:1], v = [1:0.01:5].
I first create a cell, denoted by C, to record the coordinates of this (v,z), and from this C, I fill in a matrix of the value of f(v,z). So my cell C look like the following
C = (0,5), (0.01,5), (0.02,5),....., (1,5)
(0,4.99),(0.01,4.99),(0.02,4.99),...,(1,4.99)
...
(0,1), (0.01,1), (0.02,1),......,(1,1)
So when viewing cell C as the coordinates in the 2D space, the vertical axis (the column) is z and the horizontal axis (the row) is v. And the value f(v,z) is built up on these coordinates. So one can imagining plotting a 3D picture.
Then I fill matrix M, which contains the value of f(v,z) according to the cell C. Then I want to do the heat map (or contour would also be fine), but when I use colormap or contour, it seems that matlab just does not plot the figure according to my specific direction of v and z as specified by my cell C. Also, the range of the two axes does not look right. I wonder if there is good way to control the plotting directions of the axes?

matlab bar plot: labeliing 3 bars with each only one value

I need to make a bar graph in matlab with 3 bars. The values for the three bars is stored in x. Now I want a to make a legend: Each bar should be labeled with a letter e.g. 'A','B','C'.
x = rand(1,3); bar(x); legend('A','B','C');
Did not work.
Then I tried this example: http://www.mathworks.com/matlabcentral/fileexchange/35271-matlab-plot-gallery-vertical-bar-plot/content/html/Vertical_Bar_Plot.html
But as soon as you reduce the the number of entries in each category to 1, you'll get an error message, but I think the message is wrong =/ it works with any number but just not with 1...
So is there a simple solution to that problem?
What you want is a "three series plot" - unfortunately, as soon as you make it 1x3, Matlab thinks it's just a single series. We have to trick it into thinking you have three series. Here's how you do that:
x = rand(1,3);
x2 = [x; x*0]; % add a second row of all zeros
figure
bar(x2); % now we have a plot with an ugly second category
xlim([0.5 1.5]); % trick that hides second category
legend('a','b','c'); % add the legend
set(gca, 'XTickLabel', ''); % hide the '1' on the X axis (or make it whatever you want)
title 'Bar plot with legend - demo'
Result is then something like this:
I believe this is exactly what you were asking for.

plotting 3d bar plot in matlab

I have an Nx3 matrix in matlab and I'd like to make a 3 dimensional bar graph out of it, where the X and Y axes are determined by the values of first and second columns of the matrix, the height of each bar is the third column in the matrix, and the number of bars is determined by N.
In other words, if "data" is the matrix then:
data(:, 1) % values of X-axis
data(:, 2) % values of Y-axis
data(:, 3) % values of each Z-axis bar
and there should be one bar for each 1:length(data)
How can I do this in MATLAB?
Secondly, as a variant of this, how can I do the same thing, but this time histogram the bars into N bins in each X, Y, Z dimension? I.e. instead of a bar for each point, just histogram the data into those bins in every dimension, and plot a bar for each bin.
thanks very much for your help.
Regarding your 1st question, you can achieve something similar to your request, by:
stem3 (data(:,1), data(:,2), data(:,3), 'marker', 'none', 'linewidth',10)
Not exactly bars, but produces a similar effect.
To plot 'real' bars (such as the ones bar3 plots), I think you'll have to use low-level graphics function such as surface (which is used by bar3 to plot bars).
Regarding your 2nd question, I'm not sure I understand --- if you calculate a histogram for each dimension, you end up with 4-dimensional data --- the bin location for each dimension + the hist count itself. What exactly do you want to plot?