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:
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)
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.
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.
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)
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')
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)
(the xlabel was a little buggy, so I used a tweak to get i right)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With