Adjusting plot fill to show two colours depending on overestima​​tion/unde​r​estimati​on

2 vues (au cours des 30 derniers jours)
mashtine le 27 Nov 2014
Commenté : mashtine le 9 Fév 2015
Hello,
I have the following code to plot my observed readings versus my modelled readings and the code works fine but does not clearly show regions where my modelled data is greater than observed data.
% Create figure
figure1 = figure;
XData = mod1_2001_2014(x,1)';
YData1 = mod1_2001_2014(x,5)';
YData2 = mod1_2001_2014(x,4)';
% Plot with fill
X = [XData fliplr(XData)];
Y = [YData1 fliplr(YData2)];
fill(X,Y,[0.678431391716003 0.921568632125854 1]);
ylim([0 max(YData2)+3])
I was wondering if there is a way to have this so that when the YData2 > YData1 the fill is red and when YData1 > YData2, the fill is the colour it is now.
Any ideas? Thank you!
0 commentairesAfficher -2 commentaires plus anciensMasquer -2 commentaires plus anciens

Connectez-vous pour commenter.

Réponse acceptée

Thorsten le 27 Nov 2014
Modifié(e) : Thorsten le 5 Fév 2015
or my solution that does need no interpolation but computes the intersection points.
function fillline(x, y1, y2, col1, col2)
% Thorsten Hansen 2015-05-02 2014-11-27
% http://www.mathworks.com/matlabcentral/fileexchange/34876--greater-than--fill
if nargin < 3
x = -10:10;
y1 = sin(x);
y2 = cos(x);
end
if nargin < 5
col1 = [1 0 0];
col2 = [0 0 1];
end
hold on
colpatch(y1 >= y2, col1, x, y1, y2)
colpatch(y2 >= y1, col2, x, y1, y2)
plot(x, y1, '-', 'Color', col1)
plot(x, y2, '-', 'Color', col2)
hold off
function colpatch(ind, col, x, y1, y2)
% special case 1: all values of y2 below y1: nothing to fill
if ~any(ind)
return
end
% define fill color as a lighter version of the color on the line above
col = lighten(col);
% force row vectors for proper concatenation in fill below
x = x(:)'; y1 = y1(:)'; y2 = y2(:)'; ind = ind(:)';
% special case 2: no intersections, all values of y2 above y1
if all(ind)
fill([x x(end) fliplr(x) x(1)], ...
[y1 y1(end) fliplr(y2) y2(1)], col, 'EdgeColor', col);
return
end
% general case: y1 and y2 intersect
val = cumsum(diff([0 ind]) == 1).*ind;
v = 1;
ind = find(val == v);
while ~isempty(ind)
xi = x(ind); y1i = y1(ind); y2i = y2(ind);
% determine intersections to fill area between intersections
% determine left intercept
ii = ind(1);
if ii > 1
line1 = [x(ii) y1(ii); x(ii-1) y1(ii-1)];
line2 = [x(ii) y2(ii); x(ii-1) y2(ii-1)];
[xis_left yis_left] = lineintercept(line1, line2);
else
xis_left = [];
yis_left = [];
end
% determine right intercept
ii = ind(end);
if ii < numel(x)
line1 = [x(ii) y1(ii); x(ii+1) y1(ii+1)];
line2 = [x(ii) y2(ii); x(ii+1) y2(ii+1)];
[xis_right yis_right] = lineintercept(line1, line2);
else
xis_right = [];
yis_right = [];
end
fill([xis_left xi xis_right fliplr(xi)], ...
[yis_left y1i yis_right fliplr(y2i)], col, 'EdgeColor', col);
%set(h), pause
v = v + 1; % next patch
ind = find(val == v); % indices of next patch
end
function [xis yis] = lineintercept(line1, line2)
slope = @(line) (line(2,2) - line(1,2))/(line(2,1) - line(1,1));
m1 = slope(line1);
m2 = slope(line2);
intercept = @(line,m) line(1,2) - m*line(1,1);
b1 = intercept(line1,m1);
b2 = intercept(line2,m2);
% intersection
xis = (b2-b1)/(m1-m2);
yis = m1*xis + b1;
%plot(xis,yis,'ko','MarkerSize',10)
function col = lighten(col)
col = col + 0.8*([1 1 1] - col);
6 commentairesAfficher 4 commentaires plus anciensMasquer 4 commentaires plus anciens
Thorsten le 5 Fév 2015
Hi Masao,
I missed to also force "ind" to be a row vector. Please find the updated fillline function above. Hope this works now smoothly for everything :-)
Best,
Thorsten
mashtine le 9 Fév 2015
Thank you!

Connectez-vous pour commenter.

Plus de réponses (1)

Luuk van Oosten le 27 Nov 2014
Dear Massao,
I do not know exactly how your data looks like, but you could use somthing like:
for i=1:lenght(yourdataset)
if YData1 < YData2 % Let matlab check if Ydata2 is larger than YData1
scatter( x(i,1), y(i,5), 15, [1 0 0], 'filled') hold on;
else % if this condition is not matched, then do the following:
scatter( x(i,1), y(i,4),15, [0 0.68 0.92], 'filled') hold on;
end
Have fun!
3 commentairesAfficher 1 commentaire plus ancienMasquer 1 commentaire plus ancien
Luuk van Oosten le 27 Nov 2014
Oops, excuse me. I'm not very familiar with plotting lines.
nevertheless, if you try something analogous to
if Ydata1 < Ydata2
fill stuff in fancy blue
else
fill stuff in red
I would expect that to work.
mashtine le 27 Nov 2014
Thanks Luuk but I am not sure how to do that will the flipr function

Connectez-vous pour commenter.

Catégories

En savoir plus sur Formatting and Annotation dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by