Tornado chart with colormap gradient
19 views (last 30 days)
Show older comments
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
0 Comments
Answers (2)
Star Strider
on 16 Apr 2024 at 16:47
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
.
0 Comments
Voss
on 16 Apr 2024 at 16:47
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.
0 Comments
See Also
Categories
Find more on Red in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!