Search code examples
matlabvisualizationheatmapcolormapdensity-plot

How to plot Heat Map or color map of overlapping multiple line plots in MATLAB


I have 300 line plots of altitude profile of temperature and would like to visualise it in such a way which it is more quantitative instead of just plotting the line plots. I found this plots below interesting which I would like to plot but not sure how to do it. I also like to plot mean, median and mode temperatures as given in the sample plot.

% Generate sample data
numProfiles = 300;    % Number of temperature profiles
numAltitudes = 101;   % Number of altitude points (from 0km to 100km with 1km increment)
altitude = 0:1:100;   % Altitude values in km
temperatures = zeros(numAltitudes, numProfiles);
% Generate temperatures with increased variation in specific altitude ranges
baseTemperature = 200 + altitude' * 3;     % Base temperature profile
% Generate variations for each profile
for i = 1:numProfiles
    variation = zeros(numAltitudes, 1);
    
    % Add varying magnitudes of variation at different altitude points
    for j = 1:numAltitudes
        if altitude(j) < 20
            variation(j) = randn * 50;          % Large variation
        elseif altitude(j) < 50
            variation(j) = randn * 10;          % Increased variation
        elseif altitude(j) < 70
            variation(j) = randn * 3;           % Moderate variation
        else
            variation(j) = randn * 1;           % Very small variation
        end
    end
    
    temperatures(:, i) = baseTemperature + variation;
end
% Plotting
figure;
hold on;
for i = 1:numProfiles
    plot(temperatures(:, i),altitude, 'Color', rand(1,3)); % Random color for each plot
end

I would like to visualise my data something like this


Solution

  • You can create the heatmap effect by discretising one axis, and for each "slice" calculate the density of your data. In your case this is essentially calculating a histogram for each slice of altitude, and plotting them together.

    % Create histogram bins to get data density for each slice of altitude
    nbins = 40;
    bins = linspace( min(temperatures(:)), max(temperatures(:)), nbins );
    hc = NaN(numAltitudes,nbins-1);
    for i = 1:numAltitudes
        hc(i,:) = histcounts(temperatures(i,:), bins);
    end
    % Get the centre value of each histogram bin
    temps = (bins(1:end-1)+bins(2:end))/2;
    % Get the x/y values as a mesh to plot the surface
    [x,y] = meshgrid( temps, altitude );
    figure;
    % Plot a surface with no edges, where the z-direction indicates density
    % Viewed from "above", this will look like a heatmap
    surface( x, y, hc, 'edgecolor', 'flat' );
    % Create a colour map which fades from white -> blue -> green -> yellow -> red
    c = interp1( 1:5, [1,1,1; 0,0.5,1; 0.2,1,0.2; 1,1,0; 1,0,0], linspace(1,5,20) );
    colormap(c);
    

    For your data, this gives the following improvement from random lines as in your question:

    plots

    You can play around with the discretisation (more or less granular) and colour mapping to achieve the desired look. You can also calculate the mean/median/mode for each "slice" of altitude and plot these as lines on top of the heatmap.