1

I have a problem with MATLAB bar3 plots: Here is what I have:


m x n Array Values containing values of a measurement.

Another m x n Array Angles Represents the angle at which a value was measured (e.g. the 3rd value was measured at an angle of 90°). The angular values for each measurement value are stored in another variable.


I need a range for my x-axis from -180° to +180°. This alone is no problem. But how do I hand over my measurement values? I have to somehow link them to the angular values. So that each value in Values is somehow linked to it's angular value in Angles. For my y-axis, I can simply count from 0 to the amount of rows of my Values Array.

EXAMPLE:

Valueslooks like:

3   5   6
2   1   7
5   8   2

Angles looks like:

37°   38°   39°
36°   37°   38°
34°   35°   36°

Values(1,1) = 3 was measured at Angles(1,1) = 37° for example.

Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
PKlumpp
  • 4,913
  • 8
  • 36
  • 64
  • So what should the graph be? Two bars stacked along the y axis at x=37, one at 34 etc? – Luis Mendo Sep 18 '14 at 11:12
  • Sry, I got you wrong! You are right with this! http://www.mathworks.com/matlabcentral/fileexchange/screenshots/2842/original.jpg On the x-axis, there are the angles. On the y-axis the ID of the measurement. And on z-axis, the value itself is plotted. So in my Example, we would have and x-axis ranging from 34° to 39°, a y-axis from 1 to 3, and 9 bars according to the nine values. – PKlumpp Sep 18 '14 at 11:16
  • So the number of bars at each x value can vary, right? One bar at x=34, two bars at x=37, etc – Luis Mendo Sep 18 '14 at 11:19

1 Answers1

3

At each angle, the number of bars varies depending on how many measurements exist for that angle. bar3 needs a matrix input. In order to build a matrix, missing values are filled with NaN.

Warning: NaNs are usually ignored by plotting commands, but bar3 apparently breaks this convention. It seems to replace NaNs by zeros! So at missing values you'll get a zero-height bar (instead of no bar at all).

[uAngles, ~, uAngleLabels] = unique(Angles); %// get unique values and
    %// corresponding labels
valuesPerAngle = accumarray(uAngleLabels(:), Values(:), [], @(v) {v});
    %// cell array where each cell contains all values corresponding to an angle
N = max(cellfun(@numel, valuesPerAngle));
valuesPerAngle = cellfun(@(c) {[c; NaN(N-numel(c),1)]}, valuesPerAngle);
    %// fill with NaNs to make all cells of equal lenght, so that they can be
    %// concatenated into a matrix  
valuesPerAngle = cat(2, valuesPerAngle{:}); %// matrix of values for each angle,
    %// filled with NaNs where needed
bar3(uAngles, valuesPerAngle.'); %'// finally, the matrix can be plotted
ylabel('Angles')
xlabel('Measurement')

With your example Values and Angles this gives:

enter image description here

Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
  • There's a problem. `NaN`s are not ignored by `bar3`! They give 0 instead. See edit – Luis Mendo Sep 18 '14 at 11:38
  • This is no problem atm, because values of 0 cannot be measured. so it is clear that these values do not represent something useful – PKlumpp Sep 18 '14 at 11:43
  • 1
    Should it be a problem (in a more general setting), [this approach](http://stackoverflow.com/q/24269516/2586922) could probably be adapted to remove those bars – Luis Mendo Sep 18 '14 at 11:49