NCCOOS Trac Projects: Top | Web | Platforms | Processing | Viz | Sprints | Sandbox | (Wind)

root/gliderproc/trunk/MATLAB/plots/splotyy.m

Revision 495 (checked in by cbc, 12 years ago)

Initial import of Stark code.

Line 
1 function [hy2l,ax,pl]=splotyy(arg1,arg2,arg3,arg4,arg5,arg6,arg7)
2 % SPLOTYY  Plot graphs with Y tick labels on left and right side.
3 %         SPLOTYY(x1,y1,x2,y2) plots y1 vs. x1 with y-axis labeling
4 %         on left, and plots y2 vs. x2 with y-axis labeling on right.
5 %
6 %         SPLOTYY(x1,y1,linopts1,x2,y2,linopts2) draws lines according
7 %         to (optionally) specified line types.  LINOPTS* is a string
8 %         specified according the line options for PLOT.
9 %
10 %         [hy2l] = SPLOTYY(x1,y1,x2,y2) returns the handle of the text
11 %         object used for y2label.
12 %
13 %         [hy2l,ax,pl] = SPLOTYY(x1,y1,x2,y2) additionally returns the
14 %         handles of the two axes created by plotyy in ax and the
15 %         handles of the lines created by plotyy in pl.
16 %
17 %         SPLOTYY(x1,y1,x2,y2,options) allows for an options
18 %         vector as follows:
19 %
20 %               OPTIONS(1) : 0 for linear x-axis, 1 for log x-axis
21 %               OPTIONS(2) : 0 for linear y1-axis, 1 for log y1-axis
22 %               OPTIONS(3) : 0 for linear y2-axis, 1 for log y2-axis
23 %               OPTIONS(4:5) : x-axis limits, in form [xmin xmax]
24 %               OPTIONS(6:7) : y1-axis limits, in form [y1min y1max]
25 %               OPTIONS(8:9) : y2-axis limits, in form [y2min y2max]
26 %
27 %               Specify NaN for any option to use default value.
28 %
29 %         For example,
30 %
31 %               splotyy(x1,y1,'r-',x2,y2,'g:',[0 1 0 1.5 3 nan nan 0 10])
32 %
33 %         plots y1 vs. x1 using a red solid line and y2 vs. x2 using
34 %         a green dotted line, with log y1-axis scaling an x-axis range
35 %         of 1.5 to 3, the default y1-axis range, and a y2-axis yange
36 %         of 0 to 10.
37 %
38 %         Note:  Using PLOT to replace axes created by SPLOTYY will not
39 %         replace the second y-axis.  Use SPLOTYY with empty x2 and y2
40 %         vectors, i.e., plotyy(x1,y1,[],[]).
41 %
42 % Calls: none
43 %
44 %         See also TITLE, XLABEL, YLABEL, Y2LABEL, SUBPLOT.
45
46 % Version:  2.1.1 (March 23, 1995)
47
48 %Known bugs:
49 % Due to a bug in 4.0a on Sun and SGI (and perhaps others)
50 % setting the ylabels units to normalized (so they stick with the
51 % axis as the figure is resized) does not work correctly.  In
52 % this case, the ylabel is still drawn, but it won't follow the axis
53 % around on the screen if the figure is resized.
54
55 % Modified by Samson H. Lee (shl0@lehigh.edu)
56 % 02/02/93
57 % Use actual ylabel position determined by plot(x2,y2) for second
58 % ylabel position.  Position is grabbed before plot is rotated using
59 % view function.
60 % 02/03/94
61 % Added linetype and linecolor specifications.
62 % Moved y2label to separate function.  Ylabel is all set up except for
63 % specifying the string.  A separate function y2label uses the given
64 % handle and sets the string.
65 % 03/07/94
66 % Store handles in UserData so Y2LABEL no longer requires handle
67 % passing.
68 % 03/21/95 version 2.1
69 % Added drawnow before getting typ_ylabel_pos because of a suspected
70 % bug in get()
71 % 03/23/95 version 2.1.1
72 % Tag axes as plotyy-axes
73 % If replacing plotyy axes, delete axes2 and expand axes 5%
74 % Do not plot axes2 if x2 is empty
75
76 % constants:
77 NUMOPTS  = 9;  % Maximum number of arguments in OPTIONS vector
78 OI_XLOG  = 1;  % Index of Options vector for x-axis scaling
79 OI_Y1LOG = 2;  % Index of Options vector for y1-axis scaling
80 OI_Y2LOG = 3;  % Index of Options vector for y2-axis scaling
81 OI_XMIN  = 4;  % Index of Options vector for x-axis min limit
82 OI_XMAX  = 5;  % Index of Options vector for x-axis max limit
83 OI_Y1MIN = 6;  % Index of Options vector for y1-axis min limit
84 OI_Y1MAX = 7;  % Index of Options vector for y1-axis max limit
85 OI_Y2MIN = 8;  % Index of Options vector for y2-axis min limit
86 OI_Y2MAX = 9;  % Index of Options vector for y2-axis max limit
87
88 % error checking:
89 if nargin<4,
90   error('PLOTYY requires at least 4 input arguments.');
91 elseif nargin>7,
92   error('PLOTYY accepts no more than 7 input arguments.');
93 elseif nargout>3,
94   error('PLOTYY returns a maximum of 3 output arguments.');
95 end
96
97 % parse arguments
98 linopt1=[];
99 linopt2=[];
100 options=[];
101 x1=arg1;
102 y1=arg2;
103 if isstr(arg3),
104   if nargin<5,
105     error('improper syntax');
106   end
107   linopt1=arg3;
108   x2=arg4;
109   y2=arg5;
110   if nargin>5,
111     if isstr(arg6),
112       linopt2=arg6;
113       if nargin>6,
114         options=arg7;
115       end
116     else
117       options=arg6;
118     end
119   end
120 else
121   x2=arg3;
122   y2=arg4;
123   if nargin>4,
124     if isstr(arg5),
125       linopt2=arg5;
126       if nargin>5,
127         options=arg6;
128       end
129     else
130       options=arg5;
131     end
132   end
133 end
134
135 % color matrix and mapping matrix
136 colmat=[1 1 0; 1 0 1; 0 1 1; 1 0 0; 0 1 0; 0 0 1; 1 1 1; 0 0 0];
137 for i=1:8,
138   colmap(i,i)=i;
139 end
140
141 % parse linopt1
142 lincolstr1=[];
143 linsty1=[];
144 if ~isempty(linopt1)
145   if sum(linopt1(1)=='ymcrgbwk'),       % See if first char in argument
146     lincolstr1=linopt1(1);              % is a linetype or a color
147     if length(linopt1)>1,
148       if sum(linopt1(2)=='.ox+-*:'),
149         linsty1(1)=linopt1(2);
150         if (length(linopt1)==3) & (linsty1(1)=='-'),
151           if sum(linopt1(3)=='.-'),
152             linsty1(2)=linopt1(3);
153           else,
154             error('invalid linetype specified in LINOPT1');
155           end;
156         elseif length(linopt1)~=2,
157           error('invalid linetype specified in LINOPT1');
158         end;
159       else,
160         error('invalid linetype specified in LINOPT1');
161       end;
162     end;
163   elseif sum(linopt1(1)=='.ox+-*:'),
164     linsty1(1)=linopt1(1);
165     if length(linopt1)>1,
166       if sum(linopt1(2)=='-.ymcrgbwk'),
167         if (linsty1(1)=='-') & (sum(linopt1(2)=='.-')),
168           linsty1(2)=linopt1(2);
169         elseif length(linopt1)==2,
170           if sum(linopt1(2)=='ymcrgbwk'),
171             lincolstr1=linopt1(2);
172           else,
173             error('invalid line color specified in LINOPT1');
174           end;
175         else,
176           error('invalid linetype specified in LINOPT1');
177         end;
178         if length(linopt1)==3,
179           if sum(linopt1(3)=='ymcrgbwk'),
180             lincolstr1=linopt1(3);
181           else;
182             error('invalid linecolor specified in LINOPT1');
183           end;
184         end;
185       else,
186         error('invalid LINOPT1 specified');
187       end;
188     end;
189   else,
190     error('invalid LINOPT1 specified');
191   end;
192 end;
193
194 % parse linopt2
195 lincolstr2=[];
196 linsty2=[];
197 if ~isempty(linopt2)
198   if sum(linopt2(1)=='ymcrgbwk'),       % See if first char in argument
199     lincolstr2=linopt2(1);              % is a linetype or a color
200     if length(linopt2)>1,
201       if sum(linopt2(2)=='.ox+-*:'),
202         linsty2(1)=linopt2(2);
203         if (length(linopt2)==3) & (linsty2(1)=='-'),
204           if sum(linopt2(3)=='.-'),
205             linsty2(2)=linopt2(3);
206           else,
207             error('invalid linetype specified in LINOPT2');
208           end;
209         elseif length(linopt2)~=2,
210           error('invalid linetype specified in LINOPT2');
211         end;
212       else,
213         error('invalid linetype specified in LINOPT2');
214       end;
215     end;
216   elseif sum(linopt2(1)=='.ox+-*:'),
217     linsty2(1)=linopt2(1);
218     if length(linopt2)>1,
219       if sum(linopt2(2)=='-.ymcrgbwk'),
220         if (linsty2(1)=='-') & (sum(linopt2(2)=='.-')),
221           linsty2(2)=linopt2(2);
222         elseif length(linopt2)==2,
223           if sum(linopt2(2)=='ymcrgbwk'),
224             lincolstr2=linopt2(2);
225           else,
226             error('invalid line color specified in LINOPT2');
227           end;
228         else,
229           error('invalid linetype specified in LINOPT2');
230         end;
231         if length(linopt2)==3,
232           if sum(linopt2(3)=='ymcrgbwk'),
233             lincolstr2=linopt2(3);
234           else;
235             error('invalid linecolor specified in LINOPT2');
236           end;
237         end;
238       else,
239         error('invalid LINOPT2 specified');
240       end;
241     end;
242   else,
243     error('invalid LINOPT2 specified');
244   end;
245 end;
246
247 % map color string to color number
248 lincol1=0;
249 lincol2=0;
250 if ~isempty(lincolstr1),
251   lincol1=sum((lincolstr1=='ymcrgbwk')*colmap);
252 end
253 if ~isempty(lincolstr2),
254   lincol2=sum((lincolstr2=='ymcrgbwk')*colmap);
255 end
256
257 % check for options vector:
258 if ~isempty(options),
259  options(length(options)+1:NUMOPTS)=nan*ones(NUMOPTS-length(options),1);
260 else
261  options=nan*ones(NUMOPTS,1);  % use all default values
262 end
263
264 % first calculate overall x-axis range:
265 x1min=min(x1(~isnan(x1)));
266 x2min=min(x2(~isnan(x2)));
267 x1max=max(x1(~isnan(x1)));
268 x2max=max(x2(~isnan(x2)));
269 xrange=[min(x1min,x2min) max(x1max,x2max)];
270 if ~isnan(options(OI_XMIN)),
271  xrange=[options(OI_XMIN) xrange(2)];
272 end
273 if ~isnan(options(OI_XMAX)),
274  xrange=[xrange(1) options(OI_XMAX)];
275 end
276
277 % If replacing old plotyy plot, delete axes2 and expand axis 5%
278 if get(gca,'Tag')=='plotyy-axes1',
279   axes2 = get(gca,'UserData');
280   delete(axes2);
281   axespos = get(gca,'Position');
282   set(gca,'Position',axespos+[0 0 .05 0]);
283 end
284
285 % If x2 and y2 are empty, then only plot one axis
286 if isempty(x2),
287   plot(x1,y1)
288   return
289 end
290
291 % Set up (x2,y2) plot first:
292 axes2=gca;
293 p2=plot(x2,y2);
294 drawnow;
295 typ_ylabel_pos = get(get(axes2,'YLabel'),'Position');
296 ylaboffset=-1*typ_ylabel_pos(1);
297 set(gca,'YDir','rev');  % This line and the next are the guts of plotyy.
298 view(360-200*eps,-90);  % They allow the function to display y tick
299                         % labels on the right hand side of the plot.
300
301 % set up (x1,y1) plot now:
302
303 % create a new axis in same location as the old axis:
304 axes1=axes('Position',get(axes2,'Pos'));
305
306 p1=plot(x1,y1);
307
308 % set both axes to have same x range:
309 set(axes1,'XLim',xrange);
310 set(axes2,'XLim',xrange);
311
312 % handle OPTIONS vector:
313 if options(OI_XLOG)==0,
314  set(axes1,'XScale','linear');
315  set(axes2,'XScale','linear');
316 elseif options(OI_XLOG)==1,
317  set(axes1,'XScale','log');
318  set(axes2,'XScale','log');
319 end
320 if options(OI_Y1LOG)==0,
321  set(axes1,'YScale','linear');
322 elseif options(OI_Y1LOG)==1,
323  set(axes1,'YScale','log');
324 end
325 if options(OI_Y2LOG)==0,
326  set(axes2,'YScale','linear');
327 elseif options(OI_Y2LOG)==1,
328  set(axes2,'YScale','log');
329 end
330 if ~isnan(options(OI_Y1MIN));
331  set(axes1,'YLim',get(axes1,'YLim').*[0 1]+[options(OI_Y1MIN) 0]);
332 end
333 if ~isnan(options(OI_Y1MAX));
334  set(axes1,'YLim',get(axes1,'YLim').*[1 0]+[0 options(OI_Y1MAX)]);
335 end
336 if ~isnan(options(OI_Y2MIN));
337  set(axes2,'YLim',get(axes2,'YLim').*[0 1]+[options(OI_Y2MIN) 0]);
338 end
339 if ~isnan(options(OI_Y2MAX));
340  set(axes2,'YLim',get(axes2,'YLim').*[1 0]+[0 options(OI_Y2MAX)]);
341 end
342
343 % now tidy the plot up a bit:
344 ticklen=get(axes1,'TickLength');
345 set(axes2,'TickLength',[ticklen(1) ticklen(1)]);
346 set(axes2,'TickDir',get(axes1,'TickDir'));
347 set(axes2,'XTickLabels','');
348 set(axes1,'Box','off');
349
350 % If both y1 and y2 are vectors (not matrices) make
351 % the color of y2 be the second color in the ColorOrder.
352 % (This is to make the plot aesthetic.)
353 [m1,n1]=size(y1);
354 [m2,n2]=size(y2);
355 if (m1==1 | n1==1) & (m2==1 | n2==1),
356  ColorOrd=get(axes1,'ColorOrder');
357  if size(ColorOrd,1)~=1, % in case ColorOrder only has 1 color in it
358   set(p2,'Color',ColorOrd(2,:));
359  end
360 end
361
362 % Set line options if specified
363 if min([m1 n1])~=1,
364   nlin1=n1;
365 else,
366   nlin1=1;
367 end;
368 if lincol1>0,
369   for i=1:nlin1,
370     set(p1(i),'Color',colmat(lincol1,:));
371   end;
372 end;
373 if ~isempty(linsty1)
374   for i=1:nlin1,
375     set(p1(i),'LineStyle',linsty1);
376   end;
377 end;
378 if min([m2 n2])~=1,
379   nlin2=n2;
380 else,
381   nlin2=1;
382 end;
383 if lincol2>0
384   for i=1:nlin2,
385     set(p2(i),'Color',colmat(lincol2,:));
386   end;
387 end;
388 if ~isempty(linsty2)
389   for i=1:nlin2,
390     set(p2(i),'LineStyle',linsty2);
391   end;
392 end;
393
394 % create y2label position:
395 ylab=text(0,0,'');
396 save_axes1_units=get(axes1,'Units');    % save current state
397 set(ylab,'Units','pixels');             % convert everything to
398 set(axes1,'Units','pixels');            % same units
399 axes1pos=get(axes1,'Position');
400 ylabxcoordinate=ylaboffset+axes1pos(3);
401 ylabycoordinate=typ_ylabel_pos(2);
402 set(ylab,'Position',[ylabxcoordinate ylabycoordinate]);
403 set(ylab,'HorizontalAlignment','center');
404 set(ylab,'VerticalAlignment','top');
405 set(ylab,'Rotation',90);
406 set(ylab,'FontSize',get(axes1,'FontSize'));
407 % Due to a bug in 4.0a on Sun and SGI (and perhaps others)
408 % setting the ylabels units to normalized (so they stick with the
409 % axis as the figure is resized) does not work correctly.  In
410 % this case, draw the ylabel, but set it so it won't stick to axis
411 % position:
412 if ~strcmp(version,'4.0a'),
413   set(ylab,'Units','normalized');
414 end
415
416 % restore old 'units' settings:
417 set(axes1,'Units',save_axes1_units);
418
419 % y2 label is usually clipped if using default axes position.
420 % Therefore shrink axes width by 5% to leave room for it:
421 axespos=get(axes1,'Position');
422 set([axes1,axes2],'Position',axespos-[0 0 .05 0]);
423
424 % set 'nextplot' properties to 'new'
425 %set(axes1,'NextPlot','new');
426 %set(axes2,'NextPlot','new');
427
428 % set Tags
429 set(axes1,'Tag','plotyy-axes1');
430 set(axes2,'Tag','plotyy-axes2');
431
432 % store handles
433 set(axes1,'UserData',axes2);
434 set(axes2,'UserData',ylab);
435
436 % return handles to axes and lines:
437 if nargout>0,hy2l=ylab;end
438 if nargout>1,ax=[axes1;axes2];end
439 if nargout>2,pl=[p1;p2];end
Note: See TracBrowser for help on using the browser.