Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MATLAB: How to draw a multiple horizontal bar plot with different scales and different sets of data?

I would like to plot a bar chart exactly like the on in the picture below.

enter image description here

What I am not able to do is to plot 2 sets of data, one on the left-hand side of the "0" and the one on the right-hand side respectively, using each one a different scale on the x-axis. Using the function barh there are instructions about how to move the baseline, but in this case there are 2 sets of different data with different scales.

As example, I am trying to plot the following arrays:

left = [.1; .5; .4; .6; .3]; % Scale 0-1, grows leftwards
right = [24; 17; 41; 25; 34]; % Scale 0-35, grows rightwards

Any hints please?

like image 458
Giovanni.R88 Avatar asked Jul 22 '16 11:07

Giovanni.R88


People also ask

How do you plot multiple bar graphs in MATLAB?

bar( y ) creates a bar graph with one bar for each element in y . To plot a single series of bars, specify y as a vector of length m. The bars are positioned from 1 to m along the x-axis. To plot multiple series of bars, specify y as a matrix with one column for each series.

Can you have two different scales on a graph?

Each of the scales can be shared by more than one measure. For example, in the bar chart below, two columns share the scale to the left. To the right, another scale is used for the third column, because the unit is different and the values are of totally different magnitudes.

Is it possible to plot multiple plots in MATLAB?

By default, new plots clear existing plots and reset axes properties, such as the title. However, you can use the hold on command to combine multiple plots in the same axes. For example, plot two lines and a scatter plot.


2 Answers

To handle the different scaling, you could manually multiply the values in left to be scaled, then modify the tick marks on that side.

% Automatically determine the scaling factor using the data itself
scale = max(right) / max(left);

% Create the left bar by scaling the magnitude
barh(1:numel(left), -left * scale, 'r');

hold on
barh(1:numel(right), right, 'b')    

% Now alter the ticks.
xticks = get(gca, 'xtick')

% Get the current labels
labels = get(gca, 'xtickLabel'); 

if ischar(labels); 
    labels = cellstr(labels); 
end

% Figure out which ones we need to change
toscale = xticks < 0;

% Replace the text for the ones < 0
labels(toscale) = arrayfun(@(x)sprintf('%0.2f', x), ...
                           abs(xticks(toscale) / scale), 'uniformoutput', false);

% Update the tick locations and the labels
set(gca, 'xtick', xticks, 'xticklabel', labels)

% Now add a different label for each side of the x axis
xmax = max(get(gca, 'xlim'));
label(1) = text(xmax / 2, 0, 'Right Label');
label(2) = text(-xmax/ 2, 0, 'Left Label');

set(label, 'HorizontalAlignment', 'center', 'FontWeight', 'bold', 'FontSize', 15) 

enter image description here

like image 115
Suever Avatar answered Sep 23 '22 07:09

Suever


Here's an example:

left = [.1; .5; .4; .6; .3]; % Scale 0-1, grows leftwards
right = [24; 17; 41; 25; 34]; % Scale 0-35, grows rightwards

ax_front = axes;
b_front = barh(right,0.35);
set(b_front,'facecolor',[0.2,0.4,1])
axis([-50,50,0,6])
axis off

ax_back = axes; 
b_back = barh(-left,0.35)
axis([-1,1,0,6])
set(b_back,'facecolor',[1,0.4,0.2])
set(gca, 'xtick', [-1:0.2:1])
set(gca, 'xticklabel', [[1:-0.2:0],[10:10:50]])
grid on

axes(ax_front) % bring back to front

Result:

enter image description here

like image 26
Tasos Papastylianou Avatar answered Sep 25 '22 07:09

Tasos Papastylianou