function timeplt_draw() % TIMEPLT_DRAW: Takes care of drawing routines. % %disp ( sprintf ( 'here in timeplt_draw' ) ); global timeplt_obj; N = timeplt_obj_index; eval ( 'delete ( timeplt_obj{N}.plot_axes );', '' ); % % Redo all the axes. num_axes = max(timeplt_obj{N}.istack(:) ); for i = 1:num_axes h(i) = subplot(num_axes,1,i); if ( ~isempty(timeplt_obj{N}.ylims) ) set ( h, 'YLim', timeplt_obj{N}.ylims(i,:) ); end end set ( h, 'NextPlot', 'Add' ); h = flipud(h(:)); jd = timeplt_obj{N}.jd; data = timeplt_obj{N}.data; istack = timeplt_obj{N}.istack; % % colordef white color scheme line colors defaultcmap = get ( 0, 'defaultaxescolororder' ); if ( size(istack,1) > size(defaultcmap,1) ) cmap = jet(size(istack,1)); else cmap = defaultcmap; end axis_color_index = zeros(length(istack),1); jd0 = gmin(jd(:)); jd1 = gmax(jd(:)); % % Make the time axis always extend 5 percent past the % data. timediff = jd1 - jd0; xlim = [(jd0 - timediff*0.05) (jd1 + timediff*0.05)]; set ( h, 'XLim', xlim ); % % plot the data for i = 1:length(istack) axes ( h(istack(i)) ); % % set the index into the colormap correctly % each pane is to be the same as the order for regular matlab plots. % While I'm at it, I think I will cure world hunger. axis_color_index(istack(i)) = axis_color_index(istack(i)) + 1; if ( isreal ( data(:,i) ) ) graph = plot ( jd, data(:,i) ); if ( ~isempty(timeplt_obj{N}.ylims) ) set ( gca, 'YLim', timeplt_obj{N}.ylims(istack(i),:) ); end else % % Retrieve the ylims. If ylims were specified % in the timplt call, then it has already been % set in the gca. Otherwise construct it from the % data. if ( isempty(timeplt_obj{N}.ylims) ) y0 = min ( gmin(imag(data(:,i))), 0); y1 = max ( gmax(imag(data(:,i))), 0); ylim = [y0 y1]; set ( gca, 'YLim', ylim ); else ylim = get ( gca, 'ylim' ); end % % Construct the scaling factor to accurately do % stick plots. old_units = get ( gca, 'Units' ); set ( gca, 'Units', 'Pixels' ); pos = get ( gca, 'Position' ); set ( gca, 'Units', old_units ); scale_factor = (diff(xlim)/diff(ylim)) * (pos(4)/pos(3)); u_data = scale_factor * real(data(:,i)); v_data = imag(data(:,i)); x=jd; xp=x; yp=zeros(size(xp)); xplot=ones(length(xp),2); yplot=xplot; xplot(:,1)=x(:); xplot(:,2)=xp(:)+u_data(:); xplot(:,3)=x(:); yplot(:,1)=yp(:); yplot(:,2)=yp(:)+v_data(:); yplot(:,3)=yp(:)*nan; xplot=xplot'; yplot=yplot'; if(~isempty(find(finite(u_data(:))))) graph(1) = plot( [jd0 jd1],[0 0] ); graph(2) = plot ( xplot(:), yplot(:) );... end end % index = mod(i-1, length(cmap))+1; % set ( graph, 'color', cmap(index,:) ); set ( graph, 'color', cmap(axis_color_index(istack(i)),:) ); end % % We want to do our own labels, thank you very much. set ( h, 'XTickLabel', [] ); % % What's the separation of the ticks? xt = get(gca,'XTick' ); xt_sep = max(diff(xt(:))); axes ( h(1) ); if (timeplt_obj{N}.year_cut_specified) timeplt_gregax_year ( timeplt_obj{N}.jd ); elseif (timeplt_obj{N}.month_cut_specified) timeplt_gregax_month ( timeplt_obj{N}.jd ); elseif (timeplt_obj{N}.day_cut_specified) timeplt_gregax_day ( timeplt_obj{N}.jd ); elseif (timeplt_obj{N}.hour_cut_specified) timeplt_gregax_hour( timeplt_obj{N}.jd ); elseif (timeplt_obj{N}.minute_cut_specified) timeplt_gregax_minute( timeplt_obj{N}.jd ); elseif ( xt_sep > timeplt_obj{N}.year_cut ) timeplt_gregax_year ( timeplt_obj{N}.jd ); timeplt_obj{N}.year_cut_specified = 1; elseif (xt_sep > timeplt_obj{N}.month_cut) timeplt_gregax_month ( timeplt_obj{N}.jd ); timeplt_obj{N}.month_cut_specified = 1; elseif (xt_sep > timeplt_obj{N}.day_cut) timeplt_gregax_day ( timeplt_obj{N}.jd ); timeplt_obj{N}.day_cut_specified = 1; elseif (xt_sep > timeplt_obj{N}.hour_cut) timeplt_gregax_hour( timeplt_obj{N}.jd ); timeplt_obj{N}.hour_cut_specified = 1; else timeplt_gregax_minute ( timeplt_obj{N}.jd ); timeplt_obj{N}.minute_cut_specified = 1; end % % Now make sure that all axes have the same tick marks as the first. set ( h, 'XTick', get(h(1), 'XTick' ) ); timeplt_obj{N}.plot_axes = h; % % The last thing we do is to calculate the printing properties. % We want the paperposition to come out as close as possible to % what's on screen. old_units = get( timeplt_obj{N}.figure, 'Units' ); set ( timeplt_obj{N}.figure, 'Units', 'Points' ); old_paper_units = get ( timeplt_obj{N}.figure, 'PaperUnits' ); set ( timeplt_obj{N}.figure, 'PaperUnits', 'Points' ); set ( timeplt_obj{N}.figure, 'PaperType', 'usletter' ); onscreen_position = get ( timeplt_obj{N}.figure, 'Position' ); onpaper_position = get ( timeplt_obj{N}.figure, 'PaperPosition' ); % % The maximum width that the plot can be is 612 points. Anything % larger must be scaled down. % The maximum height is 792 points. if ( onscreen_position(3) > 612 ) hreduction_factor = 612 / onscreen_position(3); else hreduction_factor = 1; end onpaper_position(3) = onscreen_position(3) * hreduction_factor; onpaper_position(4) = onscreen_position(4) * hreduction_factor; if ( onscreen_position(4) > 792 ) vreduction_factor = 792 / onscreen_position(4); else vreduction_factor = 1; end onpaper_position(3) = onpaper_position(3) * vreduction_factor; onpaper_position(4) = onpaper_position(4) * vreduction_factor; onpaper_position(1) = (612 - onpaper_position(3))/2; onpaper_position(2) = (792 - onpaper_position(3))/2; set ( timeplt_obj{N}.figure, 'PaperPosition', onpaper_position ); set ( timeplt_obj{N}.figure, 'Units', old_units ); set ( timeplt_obj{N}.figure, 'PaperUnits', old_paper_units ); return; function timeplt_gregax_day( jd ) %TIMEPLT_GREGAX_DAY: Writes gregorian axes tick labels %disp ( 'present in timeplt_gregax_day' ); month_label = [ 'Jan'; ... 'Feb';... 'Mar';... 'Apr';... 'May';... 'Jun';... 'Jul';... 'Aug';... 'Sep';... 'Oct';... 'Nov';... 'Dec']; % % First figure out the height of the bottom plot in points. % Then allow for 3 lines to fit here. old_units = get ( gca, 'Units' ); set ( gca, 'Units', 'Points' ); pos = get(gca, 'Position' ); set ( gca, 'Units', old_units ) height = pos(2); % % Fontsize should be the same as the ylabel. fsize = get ( get(gca,'YLabel'), 'Fontsize' ); % % Now figure the height of the bottom plot in user coords. ylim = get ( gca, 'YLim' ); cfactor = diff(ylim) / pos(4); xt = get ( gca, 'XTick' ); greg = gregorian ( xt(:) ); xlim = get(gca,'xlim'); % % Make sure that the minute ticks start right on the day, % and not in the middle. % Stop the ticks somewhere around the end of xlim. Don't really % care so much about this. jd0 = gmin(jd(:)); jd1 = xlim(2); start = gregorian(jd0); start = [start(1:3) 0 0 0]; jd0 = julian(start); stop = gregorian(jd1); % % We need to know how many labels to write. % Assume that we want a maximum of 50 pts between labels. max_width = 40; point_width = pos(3); dx = diff(xlim); scale_factor = dx/point_width; % number of days per point day_tic = max ( max_width*scale_factor, 1 ); % % round this up to the nearest day. day_tic = ceil(day_tic); % % do some more refinement to get good day splits if ( (day_tic >= 4) & (day_tic <6) ) day_tic = 5; elseif ( (day_tic >= 6) & (day_tic <8.5) ) day_tic = 7; elseif ( (day_tic >= 8.5) & (day_tic <12) ) day_tic = 10; elseif ( (day_tic >= 12) & (day_tic <16) ) day_tic = 14; end xt = [jd0:day_tic:jd1]; ifind = find((xt>=xlim(1)) & (xt<=xlim(2))); xt = xt(ifind); set ( gca, ... 'XTick', xt, ... 'XTickLabel', [] ); greg = gregorian(xt); % % Now label the xticks in days. gt_string = { num2str(greg(1,3)); ... month_label(greg(1,2),:); ... num2str(greg(1,1)) }; ypoint = ylim(1) - 0.5*fsize*cfactor; xt_label(1) = text ( xt(1), ypoint, 0, gt_string ); % % Keep track of where to put a label for a new month or year % by differencing the gregorian dates. Any entry that is not zero % means that the entry changed from the previous. tdiff = diff(greg(:,1:3)); for i = 2:length(xt) if ( tdiff(i-1,1) ) year_str = num2str(greg(i,1)); else year_str = ''; end if ( tdiff(i-1,2) ) month_str = month_label(greg(i,2),:); else month_str = ''; end if ( tdiff(i-1,3) ) day_str = num2str(greg(i,3)); else day_str = ''; end gt_string = { day_str; month_str; year_str }; xt_label(i) = text ( xt(i), ypoint, 0, gt_string ); end set ( xt_label, ... 'Fontsize', fsize, ... 'HorizontalAlignment', 'Center', ... 'VerticalAlignment', 'cap' ); return; function timeplt_gregax_hour( jd ) %TIMEPLT_GREGAX_HOUR: Writes gregorian axes tick labels month_label = [ 'Jan'; ... 'Feb';... 'Mar';... 'Apr';... 'May';... 'Jun';... 'Jul';... 'Aug';... 'Sep';... 'Oct';... 'Nov';... 'Dec']; % % First figure out the height of the bottom plot in points. % Then allow for 3 lines to fit here. old_units = get ( gca, 'Units' ); set ( gca, 'Units', 'Points' ); pos = get(gca, 'Position' ); set ( gca, 'Units', old_units ) height = pos(2); % % Fontsize should be the same as the ylabel. fsize = get ( get(gca,'YLabel'), 'Fontsize' ); % % Fontsize shouldn't be too large. %fsize = min ( height / 4, 12 ); % % Now figure the height of the bottom plot in user coords. ylim = get ( gca, 'YLim' ); cfactor = diff(ylim) / pos(4); xt = get ( gca, 'XTick' ); greg = gregorian ( xt(:) ); xlim = get(gca,'xlim'); % % Make sure that the hour ticks start right on the hour, % and not in the middle. % Stop the ticks somewhere around the end of xlim. Don't really % care so much about this. % Also, the first tick starts where the data starts. jd0 = gmin(jd(:)); jd1 = xlim(2); start = gregorian(jd0); start = [start(1:4) 0 0]; jd0 = julian(start); stop = gregorian(jd1); % % We need to know how many labels to write. % Assume that we want a maximum of 50 pts between labels. max_width = 40; point_width = pos(3); dx = diff(xlim); scale_factor = dx/point_width; % points per number of days hour_tic = max_width * scale_factor; % % Now round this up to the nearest minute. hour_tic = ceil ( hour_tic * 24 ) / 24; %hour_tic = ceil(max(diff(xt(:)))*24)/24; xt = [jd0:hour_tic:jd1]; ifind = find((xt>xlim(1)) & (xt=xlim(1)) & (xt<=xlim(2))); xt = xt(ifind); set ( gca, ... 'XTick', xt, ... 'XTickLabel', [] ); greg = gregorian(xt); % % Now label the xticks in days. year_str = num2str(greg(1,1)); day_str = sprintf ( '%s %2.0i', month_label(greg(1,2),:), greg(1,3) ); min_str = sprintf ( '%.0f:%02i', greg(1,4), greg(1,5) ); gt_string = { min_str; day_str; year_str }; ypoint = ylim(1) - 0.5*fsize*cfactor; xt_label(1) = text ( xt(1), ypoint, 0, gt_string ); % % Keep track of where to put a label for a new month or year % by differencing the gregorian dates. Any entry that is not zero % means that the entry changed from the previous. tdiff = diff(greg(:,1:5)); for i = 2:length(xt) if ( tdiff(i-1,1) ) year_str = num2str(greg(i,1)); else year_str = ''; end if ( tdiff(i-1,3) ) day_str = sprintf ( '%s %2.0i', month_label(greg(i,2),:), greg(i,3) ); else day_str = ''; end if ( tdiff(i-1,5) ) min_str = sprintf ( '%.0f:%02i', greg(i,4), greg(i,5) ); else min_str = ''; end gt_string = { min_str; day_str; year_str }; xt_label(i) = text ( xt(i), ypoint, 0, gt_string ); end set ( xt_label, ... 'Fontsize', round(fsize), ... 'HorizontalAlignment', 'Center', ... 'VerticalAlignment', 'cap', ... 'Tag', 'xtick labels' ); return; function timeplt_gregax_month( jd ) %TIMEPLT_GREGAX_MONTH: Writes gregorian axes tick labels month_label = [ 'Jan'; ... 'Feb';... 'Mar';... 'Apr';... 'May';... 'Jun';... 'Jul';... 'Aug';... 'Sep';... 'Oct';... 'Nov';... 'Dec']; % % First figure out the height of the bottom plot in points. % Then allow for 3 lines to fit here. old_units = get ( gca, 'Units' ); set ( gca, 'Units', 'Points' ); pos = get(gca, 'Position' ); set ( gca, 'Units', old_units ) height = pos(2); % % Fontsize should be the same as the ylabel. fsize = get ( get(gca,'YLabel'), 'Fontsize' ); % % Now figure the height of the bottom plot in user coords. ylim = get ( gca, 'YLim' ); cfactor = diff(ylim) / pos(4); xt = get ( gca, 'XTick' ); greg = gregorian ( xt(:) ); xlim = get(gca,'xlim'); % % Make sure that the minute ticks start right on the day, % and not in the middle. % Stop the ticks somewhere around the end of xlim. Don't really % care so much about this. jd0 = gmin(jd(:)); jd1 = xlim(2); start = gregorian(jd0); start = [start(1:2) 1 0 0 0]; jd0 = julian(start); stop = gregorian(jd1); % % We need to know how many labels to write. % Assume that we want a maximum of 50 pts between labels. max_width = 40; point_width = pos(3); dx = diff(xlim); scale_factor = dx/point_width; % points per number of days mon_tic = ceil ( max_width * scale_factor / 31 ); %mon_tic = ceil(max(diff(xt(:)/31))); gticks = start; last_gtick = gticks; last_jtick = julian(last_gtick); while ( last_jtick <= xlim(2) ) this_month = last_gtick(2); this_year = last_gtick(1); if ( (this_month - 1 + mon_tic) >= 12 ) this_year = this_year+1; end next_month = mod ( this_month -1 + mon_tic, 12) + 1; last_gtick = [this_year next_month 1 0 0 0]; last_jtick = julian(last_gtick); gticks = [gticks; last_gtick ]; end xt = julian(gticks); ifind = find((xt>=xlim(1)) & (xt<=xlim(2))); xt = xt(ifind); set ( gca, ... 'XTick', xt, ... 'XTickLabel', [] ); greg = gregorian(xt); % % Now figure the height of the bottom plot in user coords. ylim = get ( gca, 'YLim' ); cfactor = diff(ylim) / pos(4); % % Now label the xticks in days. year_str = num2str(greg(1,1)); month_str = month_label(greg(1,2),:); gt_string = { month_str; year_str }; ypoint = ylim(1) - 0.5*fsize*cfactor; xt_label(1) = text ( xt(1), ypoint, 0, gt_string ); % % Keep track of where to put a label for a new month or year % by differencing the gregorian dates. Any entry that is not zero % means that the entry changed from the previous. tdiff = diff(greg(:,1:2)); for i = 2:length(xt) if ( tdiff(i-1,1) ) year_str = num2str(greg(i,1)); else year_str = ''; end if ( tdiff(i-1,2) ) month_str = month_label(greg(i,2),:); else month_str = ''; end gt_string = { month_str; year_str }; xt_label(i) = text ( xt(i), ypoint, 0, gt_string ); end set ( xt_label, ... 'Fontsize', fsize, ... 'HorizontalAlignment', 'Center', ... 'VerticalAlignment', 'cap' ); return; function timeplt_gregax_year( jd ) %TIMEPLT_GREGAX_DAY: Writes gregorian axes tick labels % % First figure out the height of the bottom plot in points. % Then allow for 3 lines to fit here. old_units = get ( gca, 'Units' ); set ( gca, 'Units', 'Points' ); pos = get(gca, 'Position' ); set ( gca, 'Units', old_units ) height = pos(2); % % Fontsize should be the same as the ylabel. fsize = get ( get(gca,'YLabel'), 'Fontsize' ); % % Now figure the height of the bottom plot in user coords. ylim = get ( gca, 'YLim' ); cfactor = diff(ylim) / pos(4); xt = get ( gca, 'XTick' ); greg = gregorian ( xt(:) ); xlim = get(gca,'xlim'); % % Make sure that the minute ticks start right on the day, % and not in the middle. % Stop the ticks somewhere around the end of xlim. Don't really % care so much about this. jd0 = gmin(jd(:)); jd1 = xlim(2); start = gregorian(jd0); start = [start(1) 1 1 0 0 0]; jd0 = julian(start); stop = gregorian(jd1); % % We need to know how many labels to write. % Assume that we want a maximum of 50 pts between labels. max_width = 40; point_width = pos(3); dx = diff(xlim); scale_factor = dx/point_width; % points per number of days year_tic = ceil ( max_width * scale_factor / 365.24 ); %year_tic = ceil(max(diff(xt(:)/365.24))); gyears = start; last_gyear = start; last_jyear = julian(start); while ( last_jyear <= jd1 ) last_gyear(1) = last_gyear(1) + year_tic; last_jyear = julian(last_gyear); gyears = [gyears; last_gyear]; end xt = julian(gyears); ifind = find((xt>=xlim(1)) & (xt<=xlim(2))); xt = xt(ifind); set ( gca, ... 'XTick', xt, ... 'XTickLabel', [] ); greg = gregorian(xt); year_labels = num2str(greg(:,1)); set ( gca, 'XTickLabel', year_labels ); return; function xnew=gmin(x) %function xnew=gmin(x) % just like min, except that it skips over bad points [imax,jmax]=size(x); for j=1:jmax good=find(finite(x(:,j))); if length(good)>0 xnew(j)=min(x(good,j)); else xnew(j)=NaN; end end function xnew=gmax(x) %function xnew=gmax(x) % just like max, except that it skips over bad points [imax,jmax]=size(x); for j=1:jmax good=find(finite(x(:,j))); if length(good)>0 xnew(j)=max(x(good,j)); else xnew(j)=NaN; end end