Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add shaded area to plotyy in Matlab

I am working on a plot of environmental variables (lines) and the interquartile range for those variables from multiple years (grey shade areas) versus day of year. I'm using Matlab 2014b, and because I am using more than one axis, I'm using plotyy. My graph currently looks like this:

EnvironmentDOYPlot

I want to add the shaded region to the interquartile range for daily mean air temperature (Temp. in legend), just as I did for SWE and precipitation. The problem is that temperature uses a different axes, and when I try to define which axis to use to add the shaded 'area', I get an error:

>Error using area (line 35)
>Cannot set property to a deleted object
>
>Error in env_plot_for_stack_overflow (line 43)
>THarea=area(haxes(2),doy_mean_T(:,1),shadearea);

If I don't define which axis to use then I don't get an error, but the interquartile range plots on the precip/SWE axis, not the temperature axis.

Here is my code to reproduce the first 30 days of my figure and the error. If you copy this into a script, the problem is a little after line 40.

%% Data & definitions
SWE_stats = [1, 117.348000000000, 91.4400000000000, 141.605000000000;2, 118.533333333333, 91.4400000000000, 144.145000000000;3, 119.549333333333, 91.4400000000000, 144.780000000000;4, 121.412000000000, 96.5200000000000, 146.685000000000;5, 122.936000000000, 96.5200000000000, 146.685000000000;6, 126.153333333333, 97.7900000000000, 148.590000000000;7, 128.185333333333, 97.7900000000000, 148.590000000000;8, 129.709333333333, 102.235000000000, 151.765000000000;9, 131.572000000000, 102.235000000000, 152.400000000000;10, 132.588000000000, 102.235000000000, 154.305000000000;11, 134.789333333333, 104.140000000000, 154.940000000000;12, 136.144000000000, 104.140000000000, 156.845000000000;13, 138.006666666667, 104.775000000000, 159.385000000000;14, 138.853333333333, 104.140000000000, 159.385000000000;15, 139.022666666667, 104.140000000000, 161.290000000000;16, 140.038666666667, 107.315000000000, 161.290000000000;17, 140.546666666667, 107.315000000000, 161.290000000000;18, 142.917333333333, 109.220000000000, 163.195000000000;19, 145.457333333333, 110.490000000000, 167.005000000000;20, 148.674666666667, 109.855000000000, 173.355000000000;21, 149.860000000000, 111.760000000000, 177.165000000000;22, 152.061333333333, 111.760000000000, 179.070000000000;23, 154.093333333333, 111.760000000000, 180.340000000000;24, 155.617333333333, 111.760000000000, 182.245000000000;25, 157.818666666667, 111.760000000000, 182.245000000000;26, 158.496000000000, 112.395000000000, 184.150000000000;27, 160.020000000000, 112.395000000000, 186.055000000000;28, 161.036000000000, 112.395000000000, 186.690000000000;29, 162.390666666667, 114.300000000000, 189.230000000000;30, 163.914666666667, 114.935000000000, 189.230000000000];
doy_Sum_precip = [1, 0.169333333333333, 0, 0.254000000000000;2, 1.79840000000000, 0, 1.56350000000000;3, 0.926400000000000, 0, 0.925000000000000;4, 1.09773333333333, 0, 2.31350000000000;5, 1.70760000000000, 0, 1.65100000000000;6, 0.802866666666667, 0, 1.20650000000000;7, 1.08426666666667, 0, 0.190500000000000;8, 0.592666666666667, 0, 0.698500000000000;9, 1.32026666666667, 0, 1.46050000000000;10, 2.35740000000000, 0, 1.58750000000000;11, 1.24480000000000, 0, 1.67900000000000;12, 1.08400000000000, 0, 1.39700000000000;13, 0.377333333333333, 0, 0.790500000000000;14, 0.203200000000000, 0, 0;15, 0.304800000000000, 0, 0;16, 0.728400000000000, 0, 0.952500000000000;17, 1.78973333333333, 0, 1.01600000000000;18, 2.09146666666667, 0, 2.15900000000000;19, 3.64760000000000, 0, 8.02000000000000;20, 0.947200000000000, 0, 0.940500000000000;21, 1.81280000000000, 0, 1.20650000000000;22, 1.05040000000000, 0, 2.03200000000000;23, 1.04933333333333, 0, 1.39800000000000;24, 1.22426666666667, 0, 0.577000000000000;25, 1.21386666666667, 0, 2.14000000000000;26, 1.39800000000000, 0, 2.08300000000000;27, 0.406400000000000, 0, 0.381000000000000;28, 0.480133333333333, 0, 0.254000000000000;29, 1.04986666666667, 0, 0.190500000000000;30, 2.87186666666667, 0, 1.71450000000000];
doy_mean_T = [1, -8.09985972222222, -11.1540625000000, -4.68436979166667;2, -5.79463055555556, -8.83109375000000, -1.22841145833333;3, -6.15105277777778, -9.55364583333333, -0.743854166666667;4, -6.92336388888889, -10.3746354166667, -2.77996875000000;5, -7.25890694444444, -11.0315625000000, -4.07119791666667;6, -6.18180833333333, -10.4846354166667, -2.76178125000000;7, -5.54212777777778, -9.26921875000000, -1.93483854166667;8, -5.09104166666667, -8.83031250000000, -1.83472395833333;9, -4.96344583333333, -8.44984375000000, -1.28418229166667;10, -5.27322916666667, -7.72354166666667, -0.434656250000000;11, -5.80188055555556, -9.92223958333334, -1.75604166666667;12, -6.99728333333334, -10.4307291666667, -3.12812500000000;13, -7.50514166666667, -10.4349479166667, -2.81125520833333;14, -6.15788888888889, -8.36640625000000, -1.33665104166667;15, -5.94321805555556, -7.64838541666667, -3.19562500000000;16, -7.18778888888889, -10.8927604166667, -4.12190625000000;17, -7.81982500000000, -11.9085937500000, -2.91764062500000;18, -5.99718750000000, -10.1986458333333, -2.70777083333333;19, -4.83423333333333, -8.95630208333333, -1.95089062500000;20, -5.49905833333333, -10.3791666666667, -2.15208333333333;21, -5.49337222222222, -8.93609375000000, -2.93130208333333;22, -6.19372638888889, -9.28411458333333, -3.25116145833333;23, -5.30543611111111, -9.65098958333334, -2.07925000000000;24, -4.39752361111111, -7.25994791666667, -1.20045833333333;25, -3.94550694444445, -5.87848958333333, -0.259760416666667;26, -5.62684305555556, -6.75958333333333, -3.34563541666667;27, -6.46449444444444, -10.5350520833333, -1.48580729166667;28, -7.41584861111111, -11.0597395833333, -3.56207812500000;29, -9.58481111111111, -12.7808854166667, -6.40843750000000;30, -7.77898888888889, -11.7937500000000, -3.38882812500000];
SmallFont=14;

%% Plot example

figure(1)

% First variable: SWE
% Add shaded area between SWE 25 and 75 percentiles
shadearea=[SWE_stats(:,3), (SWE_stats(:,4)-SWE_stats(:,3))];
SWEHarea=area(SWE_stats(:,1),shadearea);
hold on;

% % Second variable: precipitation
% Add shaded area between Precip 25 and 75 percentiles
shadearea=[doy_Sum_precip(:,3), (doy_Sum_precip(:,4)-doy_Sum_precip(:,3))];
precipHarea=area(doy_Sum_precip(:,1),shadearea);

% Using plotyy allows for two y axes
[haxes,hprecip,htemp]=plotyy(doy_Sum_precip(:,1),doy_Sum_precip(:,2),doy_mean_T(:,1),doy_mean_T(:,2),'plot'); %precip and temperature
set(hprecip,'Color',[0.3,0.3,0.3],...   %precip color
    'LineWidth',3,...
    'LineStyle','-');
set(htemp,'Color',[0.3,0.3,0.3],...     %temperature color
    'LineWidth',3,...
    'LineStyle','-.');
% Add daily SWE
hSWE = plot(SWE_stats(:,1),SWE_stats(:,2),'Color',[0.3,0.3,0.3],...  % plot swe
    'LineWidth',3,...
    'LineStyle','--');

% Third variable: Mean air temperature (need to add after plotyy to add on
% same scale as mean temperature)
% Plot interquartile range of daily mean air T 
% Add shaded area between daily mean air T 25 and 75 percentiles
Tshadearea=[doy_mean_T(:,3), (doy_mean_T(:,4)-doy_mean_T(:,3))];
% THIS IS WHERE THE PROBLEM IS:
%THarea=area(haxes(2),doy_mean_T(:,1),shadearea);

hold off

% Adjust axes properties
set(haxes,{'ycolor'},{'k';'k'})  % Left color , right color ...
y1_Nticks = 5;
y2_Nticks = 5;
y1 = linspace(-150, 400, y1_Nticks);
y2 = linspace(-15, 40, y2_Nticks);
set(haxes(1),'xlim',[0 366],... % set x limits
    'ylim',[y1(1) y1(end)],...
    'ytick',y1,...
    'TickDir'     , 'out'     , ...
    'TickLength'  , [.02 .02] , ...
    'Box','off');               % get rid of top border.  See also 'linkaxes'
set(haxes(2),'xlim',[0 366],...
    'ylim',[y2(1) y2(end)],...
    'ytick',y2,...
    'TickDir'     , 'out'     , ...
    'TickLength'  , [.02 .02] , ...
    'Box','off');
set(haxes, 'FontSize', SmallFont) % Set axes font size

% Set properties for Precip IQR           
set(precipHarea(1),'FaceColor','none');           % Area below lower SD/iqr?
set(precipHarea(2),'FaceColor',[.87 .87 .87]);    % Area between upper and lower SD/iqr
set(precipHarea,'LineStyle', 'none')              % Line around shape


% Set properties for SWE IQR        
set(SWEHarea(1),'FaceColor','none');           % Area below lower SD?
set(SWEHarea(2),'FaceColor',[.87 .87 .87]);    % Area between upper and lower SD
set(SWEHarea,'LineStyle', 'none')              % Line around shape

% % Set line properties for mean Temperature IQR                  
% set(THarea(1),'FaceColor','none');           % Area below lower SD?
% set(THarea(2),'FaceColor',[.87 .87 .87]);    % Area between upper and lower SD
% set(THarea,'LineStyle', 'none')              % Line around shape

% Add legend
leg_names={'Precip.','Temp.','SWE'};
LEG = legend([hprecip;htemp;hSWE],...
    leg_names,...
    'Location','Best',...
    'FontSize',SmallFont);
set(LEG, 'Box', 'off');

% Make x and y labels
ylabel(haxes(1),'Daily Precipitation & snow water (mm)','Fontsize',SmallFont) % label left y-axis
ylabel(haxes(2),strcat('Daily Mean Air Temperature (',char(176),'C)'),'Fontsize',SmallFont) % label right y-axis
xlabel('Day of year','Fontsize',SmallFont)
like image 642
user2860703 Avatar asked May 01 '15 02:05

user2860703


People also ask

How to make a transparent plot in MATLAB?

By making the patches transparent ( alpha (x) in matlab ), plots become much more manageable. With a very simple wrapper function, this trick is as easy to use as plot (): The only issue with this method is that at the time matlab can’t export figures with transparency to illustrator. A solution is to use Juerg Schwizer’s svg export function.

Is there a way to plot confidence bounds for two colors?

This works ok for two colors, but it ain’t the prettiest. Luckily, its pretty easy to plot confidence bounds as filled patches. By making the patches transparent ( alpha (x) in matlab ), plots become much more manageable.

What is the difference between Plotto and plotyy (x1 y1 x2 y2)?

plotyy(X1,Y1,X2,Y2,'function')uses the plotting function specified by the string 'function' instead of plotto produce each graph. 'function' can be plot, semilogx, semilogy, loglog, stemor any MATLAB function that accepts the syntax: h = function(x,y)

How do I label the axes in plotyy?

You can use the handles returned by plotyyto label the axes and set the line styles used for plotting. With the axes handles you can specify the YLabelproperties of the left- and right-side y-axis: set(get(AX(1),'Ylabel'),'String','Left Y-axis') set(get(AX(2),'Ylabel'),'String','Right Y-axis')


Video Answer


1 Answers

I'm not a big fan of plotyy, it is convenient if you just want to have two plots with two axes. But at the moment you want to add something it always makes trouble. I prefer to use several independent axes objects.

I tried to modify your code to exactly achieve this. I hope you understand the changes without further comments.

Basic idea is to plot both hprecip and htemp on independent axes objects, then the XTicks of the second axes gets deleted and th y-axis moved to the right:

%% Data & definitions
SWE_stats = [1, 117.348000000000, 91.4400000000000, 141.605000000000;2, 118.533333333333, 91.4400000000000, 144.145000000000;3, 119.549333333333, 91.4400000000000, 144.780000000000;4, 121.412000000000, 96.5200000000000, 146.685000000000;5, 122.936000000000, 96.5200000000000, 146.685000000000;6, 126.153333333333, 97.7900000000000, 148.590000000000;7, 128.185333333333, 97.7900000000000, 148.590000000000;8, 129.709333333333, 102.235000000000, 151.765000000000;9, 131.572000000000, 102.235000000000, 152.400000000000;10, 132.588000000000, 102.235000000000, 154.305000000000;11, 134.789333333333, 104.140000000000, 154.940000000000;12, 136.144000000000, 104.140000000000, 156.845000000000;13, 138.006666666667, 104.775000000000, 159.385000000000;14, 138.853333333333, 104.140000000000, 159.385000000000;15, 139.022666666667, 104.140000000000, 161.290000000000;16, 140.038666666667, 107.315000000000, 161.290000000000;17, 140.546666666667, 107.315000000000, 161.290000000000;18, 142.917333333333, 109.220000000000, 163.195000000000;19, 145.457333333333, 110.490000000000, 167.005000000000;20, 148.674666666667, 109.855000000000, 173.355000000000;21, 149.860000000000, 111.760000000000, 177.165000000000;22, 152.061333333333, 111.760000000000, 179.070000000000;23, 154.093333333333, 111.760000000000, 180.340000000000;24, 155.617333333333, 111.760000000000, 182.245000000000;25, 157.818666666667, 111.760000000000, 182.245000000000;26, 158.496000000000, 112.395000000000, 184.150000000000;27, 160.020000000000, 112.395000000000, 186.055000000000;28, 161.036000000000, 112.395000000000, 186.690000000000;29, 162.390666666667, 114.300000000000, 189.230000000000;30, 163.914666666667, 114.935000000000, 189.230000000000];
doy_Sum_precip = [1, 0.169333333333333, 0, 0.254000000000000;2, 1.79840000000000, 0, 1.56350000000000;3, 0.926400000000000, 0, 0.925000000000000;4, 1.09773333333333, 0, 2.31350000000000;5, 1.70760000000000, 0, 1.65100000000000;6, 0.802866666666667, 0, 1.20650000000000;7, 1.08426666666667, 0, 0.190500000000000;8, 0.592666666666667, 0, 0.698500000000000;9, 1.32026666666667, 0, 1.46050000000000;10, 2.35740000000000, 0, 1.58750000000000;11, 1.24480000000000, 0, 1.67900000000000;12, 1.08400000000000, 0, 1.39700000000000;13, 0.377333333333333, 0, 0.790500000000000;14, 0.203200000000000, 0, 0;15, 0.304800000000000, 0, 0;16, 0.728400000000000, 0, 0.952500000000000;17, 1.78973333333333, 0, 1.01600000000000;18, 2.09146666666667, 0, 2.15900000000000;19, 3.64760000000000, 0, 8.02000000000000;20, 0.947200000000000, 0, 0.940500000000000;21, 1.81280000000000, 0, 1.20650000000000;22, 1.05040000000000, 0, 2.03200000000000;23, 1.04933333333333, 0, 1.39800000000000;24, 1.22426666666667, 0, 0.577000000000000;25, 1.21386666666667, 0, 2.14000000000000;26, 1.39800000000000, 0, 2.08300000000000;27, 0.406400000000000, 0, 0.381000000000000;28, 0.480133333333333, 0, 0.254000000000000;29, 1.04986666666667, 0, 0.190500000000000;30, 2.87186666666667, 0, 1.71450000000000];
doy_mean_T = [1, -8.09985972222222, -11.1540625000000, -4.68436979166667;2, -5.79463055555556, -8.83109375000000, -1.22841145833333;3, -6.15105277777778, -9.55364583333333, -0.743854166666667;4, -6.92336388888889, -10.3746354166667, -2.77996875000000;5, -7.25890694444444, -11.0315625000000, -4.07119791666667;6, -6.18180833333333, -10.4846354166667, -2.76178125000000;7, -5.54212777777778, -9.26921875000000, -1.93483854166667;8, -5.09104166666667, -8.83031250000000, -1.83472395833333;9, -4.96344583333333, -8.44984375000000, -1.28418229166667;10, -5.27322916666667, -7.72354166666667, -0.434656250000000;11, -5.80188055555556, -9.92223958333334, -1.75604166666667;12, -6.99728333333334, -10.4307291666667, -3.12812500000000;13, -7.50514166666667, -10.4349479166667, -2.81125520833333;14, -6.15788888888889, -8.36640625000000, -1.33665104166667;15, -5.94321805555556, -7.64838541666667, -3.19562500000000;16, -7.18778888888889, -10.8927604166667, -4.12190625000000;17, -7.81982500000000, -11.9085937500000, -2.91764062500000;18, -5.99718750000000, -10.1986458333333, -2.70777083333333;19, -4.83423333333333, -8.95630208333333, -1.95089062500000;20, -5.49905833333333, -10.3791666666667, -2.15208333333333;21, -5.49337222222222, -8.93609375000000, -2.93130208333333;22, -6.19372638888889, -9.28411458333333, -3.25116145833333;23, -5.30543611111111, -9.65098958333334, -2.07925000000000;24, -4.39752361111111, -7.25994791666667, -1.20045833333333;25, -3.94550694444445, -5.87848958333333, -0.259760416666667;26, -5.62684305555556, -6.75958333333333, -3.34563541666667;27, -6.46449444444444, -10.5350520833333, -1.48580729166667;28, -7.41584861111111, -11.0597395833333, -3.56207812500000;29, -9.58481111111111, -12.7808854166667, -6.40843750000000;30, -7.77898888888889, -11.7937500000000, -3.38882812500000];
SmallFont=14;

%% Plot example

figure(1)

ax1 = axes;  %// first axes object
% First variable: SWE
% Add shaded area between SWE 25 and 75 percentiles

shadearea=[SWE_stats(:,3), (SWE_stats(:,4)-SWE_stats(:,3))];
SWEHarea=area(ax1,SWE_stats(:,1),shadearea);
hold on;

% % Second variable: precipitation
% Add shaded area between Precip 25 and 75 percentiles
shadearea=[doy_Sum_precip(:,3), (doy_Sum_precip(:,4)-doy_Sum_precip(:,3))];
precipHarea=area(ax1,doy_Sum_precip(:,1),shadearea);

% plots on diffent axes
ax2 = axes('Position',ax1.Position,'Color','none'); %// second axes object
hprecip = plot(doy_Sum_precip(:,1),doy_Sum_precip(:,2),'parent',ax1); hold on
htemp = plot(doy_mean_T(:,1),doy_mean_T(:,2),'parent',ax2); hold on
set(hprecip,'Color',[0.3,0.3,0.3],...   %precip color
    'LineWidth',3,...
    'LineStyle','-');
set(htemp,'Color',[0.3,0.3,0.3],...     %temperature color
    'LineWidth',3,...
    'LineStyle','-.');
% Add daily SWE
hSWE = plot(SWE_stats(:,1),SWE_stats(:,2),'Color',[0.3,0.3,0.3],...  % plot swe
    'LineWidth',3,...
    'LineStyle','--','parent',ax1); ; hold on

% Third variable: Mean air temperature (need to add after plotyy to add on
% same scale as mean temperature)
% Plot interquartile range of daily mean air T 
% Add shaded area between daily mean air T 25 and 75 percentiles
Tshadearea=[doy_mean_T(:,3), (doy_mean_T(:,4)-doy_mean_T(:,3))];
% THIS IS WHERE THE PROBLEM IS:
THarea = area(doy_mean_T(:,1),shadearea,'parent',ax2);

ax2.YAxisLocation = 'right'
ax2.XTick = []

hold off

% Adjust axes properties
set(ax1,'ycolor','k')  % Left color , right color ...
set(ax2,'ycolor','k')  % Left color , right color ...
y1_Nticks = 5;
y2_Nticks = 5;
y1 = linspace(-150, 400, y1_Nticks);
y2 = linspace(-15, 40, y2_Nticks);
set(ax1,'xlim',[0 366],... % set x limits
    'ylim',[y1(1) y1(end)],...
    'ytick',y1,...
    'TickDir'     , 'out'     , ...
    'TickLength'  , [.02 .02] , ...
    'Box','off');               % get rid of top border.  See also 'linkaxes'
set(ax2,'xlim',[0 366],...
    'ylim',[y2(1) y2(end)],...
    'ytick',y2,...
    'TickDir'     , 'out'     , ...
    'TickLength'  , [.02 .02] , ...
    'Box','off');
set(ax1, 'FontSize', SmallFont) % Set axes font size
set(ax2, 'FontSize', SmallFont) % Set axes font size

% Set properties for Precip IQR           
set(precipHarea(1),'FaceColor','none');           % Area below lower SD/iqr?
set(precipHarea(2),'FaceColor',[.87 .87 .87]);    % Area between upper and lower SD/iqr
set(precipHarea,'LineStyle', 'none')              % Line around shape


% Set properties for SWE IQR        
set(SWEHarea(1),'FaceColor','none');           % Area below lower SD?
set(SWEHarea(2),'FaceColor',[.87 .87 .87]);    % Area between upper and lower SD
set(SWEHarea,'LineStyle', 'none')              % Line around shape

% % Set line properties for mean Temperature IQR                  
set(THarea(1),'FaceColor','none');           % Area below lower SD?
set(THarea(2),'FaceColor',[.87 .87 .87]);    % Area between upper and lower SD
set(THarea,'LineStyle', 'none')              % Line around shape

% Add legend
leg_names={'Precip.','Temp.','SWE'};
LEG = legend([hprecip;htemp;hSWE],...
    leg_names,...
    'Location','Best',...
    'FontSize',SmallFont);
set(LEG, 'Box', 'off');

% Make x and y labels
ylabel(ax1,'Daily Precipitation & snow water (mm)','Fontsize',SmallFont) % label left y-axis
ylabel(ax2,strcat('Daily Mean Air Temperature (',char(176),'C)'),'Fontsize',SmallFont) % label right y-axis
xlabel({'','Day of year'},'Fontsize',SmallFont)

enter image description here

(the xlabel was a little buggy, so I used a tweak to get i right)

like image 66
Robert Seifert Avatar answered Sep 17 '22 19:09

Robert Seifert