matlabbar-chartlegendmatlab-figure

Add Additional Legends for Specific Bar Colors in MATLAB Bar Chart


I have the following MATLAB code, which visualizes the difference between DCO-OFDM and m-CAP in terms of coverage area vs. QAM order. The bars represent the coverage area under various configurations, and some of the bar segments are in red and blue, indicating specific effects (e.g., LOS+NLOS).

The current legend already describes the configurations (e.g., angles for m-CAP and DCO-OFDM). However, I want to add two additional legend entries specifically for the red and blue bar segments to explain their significance, as shown in the attached image.

The goal is to add two additional legends under the existing ones, representing:

Here's the image that clarifies the desired legend layout:

enter image description here

May I get assistance in achieving this? Specifically:

Here’s an example of my MATLAB code for creating the bar chart:

close all;
clear variables;
clc;

QAM = [16, 32, 64, 128, 256, 512, 1024];

%% m_CAP modulation

% Beamsteering without reflection
VEC_Beam_no_reflection_mCAP = [
    117.5491   75.1933   53.5396   38.3105   23.0815   13.5634    6.9007; % Theta = 10
    118.2629   76.1452   54.0155   39.0244   23.0815   13.5634    6.9007; % Theta = 30
    118.2629   76.3831   54.0155   39.5003   22.8435   13.5634    6.9007; % Theta = 45
    118.2629   76.6211   54.2534   39.5003   22.8435   13.5634    6.9007  % Theta = 60
];

% Beamsteering with reflection
VEC_Beam_reflection_mCAP = [
    121.3563   77.0970   54.7293   39.7383   22.8435   13.5634    6.9007; % Theta = 10
    141.1065   88.7567   61.6300   42.5937   24.2713   14.5152    7.8525; % Theta = 30
    153.7180   95.6573   67.8168   45.6871   26.6508   14.5152    8.8043; % Theta = 45
    160.3807  100.6544   69.7204   50.4462   28.7924   16.4188    8.8043  % Theta = 60
];

%% DCO-OFDM modulation

% Beamsteering without reflection
VEC_Beam_no_reflection_OFDM = [
    91.3742   59.7264   42.1178   28.7924   16.4188    8.8043    4.9970; % Theta = 10
    95.4194   58.2986   34.7412   25.9369   16.4188   10.7079    4.9970; % Theta = 30
    89.4706   59.4884   44.4973   24.7472   16.4188    8.8043    4.9970; % Theta = 45
    83.5217   69.4825   40.2142   28.7924   16.4188   10.7079    4.9970  % Theta = 60
];

% Beamsteering with reflection
VEC_Beam_reflection_OFDM = [
    94.7055   61.8679   42.1178   28.7924   16.4188    8.8043    4.9970; % Theta = 10
    113.9798   69.7204   42.1178   28.7924   16.4188   10.7079    4.9970; % Theta = 30
    115.6454   74.9554   55.6811   28.7924   16.4188    9.7561    4.9970; % Theta = 45
    114.4557   88.7567   50.6841   34.5033   21.1779   11.6597    4.9970  % Theta = 60
];

%% Combine Data for Bar Chart
angles = [10, 30, 45, 60];
data_no_reflection = [VEC_Beam_no_reflection_mCAP; VEC_Beam_no_reflection_OFDM];
data_with_reflection = [VEC_Beam_reflection_mCAP; VEC_Beam_reflection_OFDM];

% Generate gradient colors for m-CAP (blue) and DCO-OFDM (green)
mCAP_blue_gradient = [linspace(0.8, 0.1, 4)', linspace(0.9, 0.2, 4)', linspace(1.0, 0.3, 4)']; % Light to dark blue
DCO_green_gradient = [linspace(0.7, 0.1, 4)', linspace(0.9, 0.4, 4)', linspace(0.6, 0.2, 4)']; % Light to dark green

% Combine colors
custom_colors = [mCAP_blue_gradient; DCO_green_gradient];

f = figure('Position', [100, 100, 800, 600]);

% Set "HandleVisibility" to off so these bars don't appear in legend
b2 = bar(data_with_reflection', 'grouped','HandleVisibility','off');
for k = 1:length(b2)
    b2(k).FaceColor = 'flat';
    b2(k).CData = repmat([1,0,0], size(b2(k).CData, 1), 1); % [1,0,0] for red bars
end

% Plot for No Reflection
hold on; % To plot 2nd set of bars on top

b1 = bar(data_no_reflection', 'grouped');
for k = 1:length(b1)
    b1(k).FaceColor = 'flat';
    b1(k).CData = repmat(custom_colors(k, :), size(b1(k).CData, 1), 1);
end

% Adjust axis and grid
grid on;
xticks(1:length(QAM));
xticklabels(string(QAM));
xlabel('QAM Order, M');
ylabel('Coverage Area (m²)');
title({'Coverage Area With Reflection', 'm-CAP and DCO-OFDM'});

% Update the legend
legend(["m-CAP \Phi_{1/2}=10°", "m-CAP \Phi_{1/2}=30°", "m-CAP \Phi_{1/2}=45°", "m-CAP \Phi_{1/2}=60°", ...
        "DCO-OFDM \Phi_{1/2}=10°", "DCO-OFDM \Phi_{1/2}=30°", "DCO-OFDM \Phi_{1/2}=45°", "DCO-OFDM \Phi_{1/2}=60°"], ...
       'Location', 'Best');

Solution

  • You can create two fake bar plots with those colors, using NaN values so that the bars are not shown in the graph but they appear in the legend.

    To do this, replace your last line by

    bar(NaN, NaN, 'r') % fake red bar
    bar(NaN, NaN, 'b') % fake blue bar
    
    % Update the legend
    legend(["m-CAP \Phi_{1/2}=10°", "m-CAP \Phi_{1/2}=30°", ...
            "m-CAP \Phi_{1/2}=45°", "m-CAP \Phi_{1/2}=60°", ...
            "DCO-OFDM \Phi_{1/2}=10°", "DCO-OFDM \Phi_{1/2}=30°", ...
            "DCO-OFDM \Phi_{1/2}=45°", "DCO-OFDM \Phi_{1/2}=60°", ...
            "Red, \Phi_{1/2}=60°", "Blue, \Phi_{1/2}=60°"], ... % text for red and blue
            'Location', 'Best');