Clear Filters
Clear Filters

Tornado chart with colormap gradient

15 views (last 30 days)
Deborah
Deborah on 16 Apr 2024
Answered: Voss on 16 Apr 2024
Hi all,
I have created the following code in order to generate a tornado chart with the 'jet' color map gradient with +1 being blue and -1 being red; however, it isn't working! can you please help?
% Data
data = [0.496; % Electrical conversion efficiency
0.426; % Biogas efficiency value
0.399; % Biogas potential
0.386; % NPK Mineral fertiliser cost
0.264; % Methane content
0.219; % Volatile solids
0.009; % FE
-0.005; % Heat Conversion efficiency
-0.007; % Capital (Installed) cost
-0.016; % Variable O&M
-0.031; % GWP
-0.038; % POP
-0.074; % Fixed O&M
-0.100; % AP
-0.211]; % Parasitic load value
% Sort data
[sortedData, idx] = sort(data);
% Create tornado chart
figure;
barh(sortedData, 'FaceColor', 'flat');
colormap(flipud(jet)); % Blue to Red gradient
yticks(1:length(data));
yticklabels({'FE', 'Heat Conversion efficiency', 'Capital (Installed) cost', ...
'Variable O&M', 'GWP', 'POP', 'Fixed O&M', 'AP', 'Parasitic load value', ...
'Methane content', 'Volatile solids', 'Biogas potential', ...
'Biogas efficiency value', 'Electrical conversion efficiency'});
xlabel('Impact');
title('Tornado Chart');
grid on;
% Color bars based on positive (blue) and negative (red) values
for i = 1:length(data)
if data(idx(i)) >= 0
colormapIndex = ceil(data(idx(i))/max(data)*size(jet, 1)/2);
colorIndex = size(jet, 1)/2 + colormapIndex;
else
colormapIndex = ceil(data(idx(i))/min(data)*size(jet, 1)/2);
colorIndex = size(jet, 1)/2 - colormapIndex + 1;
end
colormapIndex = max(min(colormapIndex, size(jet, 1)/2), 1);
colorIndex = max(min(colorIndex, size(jet, 1)), 1);
color = jet(colorIndex, :);
barh(i, sortedData(i), 'FaceColor', color, 'EdgeColor', color);
end
Unrecognized function or variable 'jet'.

Answers (2)

Star Strider
Star Strider on 16 Apr 2024
Perhaps something like this —
% Data
data = [0.496; % Electrical conversion efficiency
0.426; % Biogas efficiency value
0.399; % Biogas potential
0.386; % NPK Mineral fertiliser cost
0.264; % Methane content
0.219; % Volatile solids
0.009; % FE
-0.005; % Heat Conversion efficiency
-0.007; % Capital (Installed) cost
-0.016; % Variable O&M
-0.031; % GWP
-0.038; % POP
-0.074; % Fixed O&M
-0.100; % AP
-0.211]; % Parasitic load value
% Sort data
[sortedData, idx] = sort(data);
% Create tornado chart
cm = colormap(flipud(jet(numel(data)))); % Blue to Red gradient
figure;
hb = barh(sortedData, 'FaceColor', 'flat');
% colormap(flipud(jet)); % Blue to Red gradient
for k = 1:numel(data)
hb.CData(k,:) = cm(k,:);
end
yticks(1:length(data));
yticklabels({'FE', 'Heat Conversion efficiency', 'Capital (Installed) cost', ...
'Variable O&M', 'GWP', 'POP', 'Fixed O&M', 'AP', 'Parasitic load value', ...
'Methane content', 'Volatile solids', 'Biogas potential', ...
'Biogas efficiency value', 'Electrical conversion efficiency'});
xlabel('Impact');
title('Tornado Chart');
grid on;
% Color bars based on positive (blue) and negative (red) values
% for i = 1:length(data)
% if data(idx(i)) >= 0
% colormapIndex = ceil(data(idx(i))/max(data)*size(jet, 1)/2);
% % colorIndex = size(jet, 1)/2 + colormapIndex;
% else
% colormapIndex = ceil(data(idx(i))/min(data)*size(jet, 1)/2);
% % colorIndex = size(jet, 1)/2 - colormapIndex + 1;
% end
% colormapIndex = max(min(colormapIndex, size(jet, 1)/2), 1);
% % colorIndex = max(min(colorIndex, size(jet, 1)), 1);
% % color = jet(cm, :);
% color = colorIndex(i,:)
% barh(i, sortedData(i), 'FaceColor', color, 'EdgeColor', color);
% % hb.CData = color;
%
% end
.

Voss
Voss on 16 Apr 2024
jet is a function that takes up to 1 input argument (the number of colors - call it N) and returns a colormap (which is an N-by-3 matrix).
So you can do this
size(jet,1)
because that calls the jet function with no inputs, in which case jet uses a default value for the number of colors N and returns an N-by-3 matrix, thus size(jet,1) is equivalent to size(jet(),1) which is the number of rows of the matrix returned by jet(), which is N.
But you cannot do this:
jet(colorIndex, :)
because for that to work jet would have to be a variable, but jet is a function.
That was the main problem with the code. To get around it, store the matrix returned by the jet function:
cmap = jet();
and use that where you subsequently use jet.
After changing that, the code ran, but it didn't give the intended result, because a hold on was needed, and also the first barh call can be removed, and the various bars plotted before setting the yticks/labels, etc.
% Data
data = [0.496; % Electrical conversion efficiency
0.426; % Biogas efficiency value
0.399; % Biogas potential
0.386; % NPK Mineral fertiliser cost
0.264; % Methane content
0.219; % Volatile solids
0.009; % FE
-0.005; % Heat Conversion efficiency
-0.007; % Capital (Installed) cost
-0.016; % Variable O&M
-0.031; % GWP
-0.038; % POP
-0.074; % Fixed O&M
-0.100; % AP
-0.211]; % Parasitic load value
% Sort data
[sortedData, idx] = sort(data);
% Create tornado chart
figure;
% Color bars based on positive (blue) and negative (red) values
cmap = jet();
N = size(cmap, 1);
for i = 1:length(data)
if data(idx(i)) >= 0
colormapIndex = ceil(data(idx(i))/max(data)*N/2);
colorIndex = N/2 + colormapIndex;
else
colormapIndex = ceil(data(idx(i))/min(data)*N/2);
colorIndex = N/2 - colormapIndex + 1;
end
colormapIndex = max(min(colormapIndex, N/2), 1);
colorIndex = max(min(colorIndex, N), 1);
color = cmap(colorIndex, :);
barh(i, sortedData(i), 'FaceColor', color, 'EdgeColor', color);
hold on
end
yticks(1:length(data));
yticklabels({'FE', 'Heat Conversion efficiency', 'Capital (Installed) cost', ...
'Variable O&M', 'GWP', 'POP', 'Fixed O&M', 'AP', 'Parasitic load value', ...
'Methane content', 'Volatile solids', 'Biogas potential', ...
'Biogas efficiency value', 'Electrical conversion efficiency'});
xlabel('Impact');
title('Tornado Chart');
grid on;
It's likely that you can also simplify the logic for mapping each data value to a colormap color, but I didn't change that.

Tags

Products


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!