How to intersect parts of two contourf Plots.

16 Ansichten (letzte 30 Tage)
Steve
Steve am 11 Okt. 2024
Kommentiert: Mathieu NOE am 11 Okt. 2024
Hello,
i tried to find a nice solution, but couldnt find quite what i seem to need.
I have Data Z1 and Z2 to a fixed X and Y - Grid.
I want Z1 and Z2 to plot as contourf-Plots. Check!
Furthermore i want to show areas in these plots below a certain level (level1 for Z1 and level2 for Z2). Check!
Lastly i want to show the intersection of these areas (without Z-Data, you could say projected to Z=0). Problem!
A lot of suggestions here, said i could try it with masked Data for Z1 and Z2.
The problem is:
Contourf interpolates and most likely smooths Data, in a way i dont know.
So the expected intersection, when seeing the contourf-Plots is not the intersection i receive, when using the "mask"-approach.
For me, it seems to be impossible to get the interpolated Data from contourf.
I tried to work out a way to get polygons using the contour-lines. But its not a quite easy way,
a) because the polygons are not covering the whole area, when the contour-lines arent closed (first point = last point).
b) because its not clear to me, whether Data are under oder above level1/level2 when surrounded by the contour-lines
Does anybody have a idea for a nice solution?
Thanks a lot!
Kind regards Steve
Results of "my Solution":
I'm looking for the Intersection of the white areas in the first row.
2nd and 3rd row are showing my current "Solution". In 3rd row i interpolated to a higher resolution (most likely similar to contourf).
But the contourf of Z1 in higher Resolution (3rd row, 1st column) is not quite the same like Contourf of Z1 (1st row, 1st column).
In this case it will lead to the correct intersection. But just because Z2 isnt covering the differing part of Z1.
Code:
% Given Data
X = [8, 12, 16, 20, 24, 28, 32];
Y = [8, 20, 32, 44, 56, 68, 80];
Z1 = [0.2795, 0.2799, 0.2814, 0.2817, 0.2800, 0.2809, 0.2808;
0.2786, 0.3040, 0.3093, 0.3113, 0.3130, 0.3131, 0.3118;
0.2824, 0.2908, 0.2975, 0.2997, 0.2992, 0.2922, 0.2930;
0.2864, 0.2847, 0.2871, 0.2798, 0.2753, 0.2714, 0.2686;
0.2850, 0.2776, 0.2802, 0.2699, 0.2684, 0.2680, 0.2681;
0.2851, 0.2830, 0.2732, 0.2684, 0.2678, 0.2684, 0.2688;
0.2857, 0.2824, 0.2747, 0.2688, 0.2668, 0.2690, 0.2687];
Z2 = [0.0517, 0.0524, 0.0526, 0.0526, 0.0527, 0.0527, 0.0527;
0.0523, 0.0626, 0.0641, 0.0640, 0.0636, 0.0636, 0.0636;
0.0549, 0.0566, 0.0577, 0.0578, 0.0576, 0.0563, 0.0575;
0.0552, 0.0547, 0.0539, 0.0523, 0.0497, 0.0482, 0.0476;
0.0547, 0.0533, 0.0521, 0.0486, 0.0473, 0.0473, 0.0474;
0.0544, 0.0525, 0.0507, 0.0475, 0.0475, 0.0476, 0.0477;
0.0542, 0.0520, 0.0500, 0.0474, 0.0476, 0.0477, 0.0478];
level1 = 0.28;
level2 = 0.05;
% Mask Z1 and Z2
Z1_masked = Z1;
Z1_masked(Z1 > level1) = NaN;
Z2_masked = Z2;
Z2_masked(Z2 > level2) = NaN;
% Plot of masked contourf Plots
figure;
subplot(3, 3, 1);
contourf(X, Y, Z1, [level1 level1], 'LineColor', 'none');
title('Contourf Z1 (below Level1 = white)');
subplot(3, 3, 4);
contourf(X, Y, Z1_masked, 'LineColor', 'none');
title('Contourf Z1-masked');
subplot(3, 3, 2);
contourf(X, Y, Z2, [level2 level2], 'LineColor', 'none');
title('Contourf Z2 (below Level2 = white)');
subplot(3, 3, 5);
contourf(X, Y, Z2_masked, 'LineColor', 'none');
title('Contourf Z2-masked');
% Find Intersection
intersection_mask = ~isnan(Z1_masked) & ~isnan(Z2_masked); % True, if both masked Z have non-NaN-Value
Z_intersection = NaN(size(Z1_masked));
Z_intersection(intersection_mask) = min(Z1_masked(intersection_mask), Z2_masked(intersection_mask));
% Plot Intersection
subplot(3, 3, 6);
contourf(X, Y, Z_intersection, 'LineColor', 'none');
title('Intersection of both contourf-Plots');
% Higher Resolution
[X_highRes,Y_highRes] = meshgrid([8:0.05:32],[8:0.05:80]);
% Z1_highRes = interp2(X, Y, Z1, X_highRes, Y_highRes, 'linear'); % Interpolation der Z-Werte
% Z1_highRes = interp2(X, Y, Z1, X_highRes, Y_highRes, 'cubic'); % Interpolation der Z-Werte
% Z1_highRes = interp2(X, Y, Z1, X_highRes, Y_highRes, 'makima'); % Interpolation der Z-Werte
% Z1_highRes = interp2(X, Y, Z1, X_highRes, Y_highRes, 'spline'); % Interpolation der Z-Werte
Z1_highRes = griddata(X, Y, Z1, X_highRes, Y_highRes, 'linear'); % Interpolation der Z-Werte
% Z1_highRes = griddata(X, Y, Z1, X_highRes, Y_highRes, 'cubic'); % Interpolation der Z-Werte
% Z1_highRes = griddata(X, Y, Z1, X_highRes, Y_highRes, 'v4'); % Interpolation der Z-Werte
% Z1_highRes = griddata(X, Y, Z1, X_highRes, Y_highRes, 'natural'); % Interpolation der Z-Werte
% Z2_highRes = interp2(X, Y, Z2, X_highRes, Y_highRes, 'linear'); % Interpolation der Z-Werte
% Z2_highRes = interp2(X, Y, Z2, X_highRes, Y_highRes, 'cubic'); % Interpolation der Z-Werte
% Z2_highRes = interp2(X, Y, Z2, X_highRes, Y_highRes, 'makima'); % Interpolation der Z-Werte
% Z2_highRes = interp2(X, Y, Z2, X_highRes, Y_highRes, 'spline'); % Interpolation der Z-Werte
Z2_highRes = griddata(X, Y, Z2, X_highRes, Y_highRes, 'linear'); % Interpolation der Z-Werte
% Z2_highRes = griddata(X, Y, Z2, X_highRes, Y_highRes, 'cubic'); % Interpolation der Z-Werte
% Z2_highRes = griddata(X, Y, Z2, X_highRes, Y_highRes, 'v4'); % Interpolation der Z-Werte
% Z2_highRes = griddata(X, Y, Z2, X_highRes, Y_highRes, 'natural'); % Interpolation der Z-Werte
% Mask Z1_highRes and Z2_highRes
Z1_highRes_masked = Z1_highRes;
Z1_highRes_masked(Z1_highRes > level1) = NaN;
Z2_highRes_masked = Z2_highRes;
Z2_highRes_masked(Z2_highRes > level2) = NaN;
% Find Intersection of HighRes_contourf
intersection_mask_highRes = ~isnan(Z1_highRes_masked) & ~isnan(Z2_highRes_masked); % True, if both masked Z have non-NaN-Value
% Z_intersection_highRes = NaN(size(Z1_highRes_masked));
% Z_intersection_highRes(intersection_mask) = min(Z1_highRes_masked(intersection_mask_highRes), Z2_highRes_masked(intersection_mask_highRes));
subplot(3,3,7)
contourf(X_highRes, Y_highRes, Z1_highRes_masked, 'LineColor', 'none');
title('Contourf Z1-highRes-masked');
subplot(3,3,8)
contourf(X_highRes, Y_highRes, Z2_highRes_masked, 'LineColor', 'none');
title('Contourf Z2-highRes-masked');
subplot(3,3,9)
contourf(X_highRes, Y_highRes, intersection_mask_highRes, 'LineColor', 'none');
title('Intersection of both HighRes-contourf-Plots');
  1 Kommentar
Mathieu NOE
Mathieu NOE am 11 Okt. 2024
hello
seems to me your approach is fine and gives the expected result
if that helps , see below some code I put together to better visualize the "separation" lines on the raw data (low res)
maybe those curves can help you in your project
clc
clearvars
% Given Data
X = [8, 12, 16, 20, 24, 28, 32];
Y = [8, 20, 32, 44, 56, 68, 80];
Z1 = [0.2795, 0.2799, 0.2814, 0.2817, 0.2800, 0.2809, 0.2808;
0.2786, 0.3040, 0.3093, 0.3113, 0.3130, 0.3131, 0.3118;
0.2824, 0.2908, 0.2975, 0.2997, 0.2992, 0.2922, 0.2930;
0.2864, 0.2847, 0.2871, 0.2798, 0.2753, 0.2714, 0.2686;
0.2850, 0.2776, 0.2802, 0.2699, 0.2684, 0.2680, 0.2681;
0.2851, 0.2830, 0.2732, 0.2684, 0.2678, 0.2684, 0.2688;
0.2857, 0.2824, 0.2747, 0.2688, 0.2668, 0.2690, 0.2687];
Z2 = [0.0517, 0.0524, 0.0526, 0.0526, 0.0527, 0.0527, 0.0527;
0.0523, 0.0626, 0.0641, 0.0640, 0.0636, 0.0636, 0.0636;
0.0549, 0.0566, 0.0577, 0.0578, 0.0576, 0.0563, 0.0575;
0.0552, 0.0547, 0.0539, 0.0523, 0.0497, 0.0482, 0.0476;
0.0547, 0.0533, 0.0521, 0.0486, 0.0473, 0.0473, 0.0474;
0.0544, 0.0525, 0.0507, 0.0475, 0.0475, 0.0476, 0.0477;
0.0542, 0.0520, 0.0500, 0.0474, 0.0476, 0.0477, 0.0478];
level1 = 0.28;
level2 = 0.05;
figure(1),
imagesc(X,Y,Z1)
set(gca,'YDir','normal');
hold on
[xc1,yc1,zc1] = my_isoclines(X,Y,Z1,level1);
for k = 1:numel(xc1)
plot(xc1{k},yc1{k},'*-r','linewidth',5);
end
hold off
figure(2),
imagesc(X,Y,Z2)
set(gca,'YDir','normal');
hold on
[xc2,yc2,zc2] = my_isoclines(X,Y,Z2,level2);
for k = 1:numel(xc2)
plot(xc2{k},yc2{k},'*-g','linewidth',5);
end
hold off
% plot the xc,yc curves on same figure
figure
hold on
for k = 1:numel(xc1)
plot(xc1{k},yc1{k},'*-r','linewidth',5);
end
for k = 1:numel(xc2)
plot(xc2{k},yc2{k},'*-g','linewidth',5);
end
hold off
%%%%%%%%%%%%%%%%%%%
function [xc,yc,zc] = my_isoclines(X,Y,Z,level)
[C,~] = contour(X,Y,Z,level*[1 1]);
[~,n] = size(C);
ind = find(C(1,:)==level); % index of beginning of each isocline data in C
ind = [ind n+1]; % add end (+1)
for k = 1:numel(ind)-1
xc{k} = C(1,ind(k)+1:ind(k+1)-1);
yc{k} = C(2,ind(k)+1:ind(k+1)-1);
zc{k} = level*ones(size(xc));
% plot3(xc,yc,zc,'*-r','markersize',15);
end
end

Melden Sie sich an, um zu kommentieren.

Antworten (0)

Produkte


Version

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by