def reset_ticks(ax, sim=None, date_args=None, start_day=None): ''' Set the tick marks, using dates by default ''' # Handle options date_args = sc.objdict(date_args) # Ensure it's not a regular dict if start_day is None and sim is not None: start_day = sim['start_day'] # Handle start and end days xmin, xmax = ax.get_xlim() if date_args.start_day: xmin = float(sc.day(date_args.start_day, start_day=start_day)) # Keep original type (float) if date_args.end_day: xmax = float(sc.day(date_args.end_day, start_day=start_day)) ax.set_xlim([xmin, xmax]) # Set the x-axis intervals if date_args.interval: ax.set_xticks(np.arange(xmin, xmax + 1, date_args.interval)) # Set xticks as dates if date_args.as_dates: date_formatter(start_day=start_day, dateformat=date_args.dateformat, ax=ax) if not date_args.interval: ax.xaxis.set_major_locator(ticker.MaxNLocator(integer=True)) # Handle rotation if date_args.rotation: ax.tick_params(axis='x', labelrotation=date_args.rotation) return
def reset_ticks(ax, sim=None, date_args=None, start_day=None, n_cols=1): ''' Set the tick marks, using dates by default ''' # Handle options date_args = sc.objdict(date_args) # Ensure it's not a regular dict if start_day is None and sim is not None: start_day = sim['start_day'] # Set xticks as dates d_args = {k: date_args.pop(k) for k in ['as_dates', 'dateformat'] } # Pop these to handle separately if d_args['as_dates']: if d_args[ 'dateformat'] is None and n_cols >= 3: # Change default date format if more than 2 columns are shown d_args['dateformat'] = 'concise' if d_args['dateformat'] in [ 'covasim', 'sciris', 'auto', 'matplotlib', 'concise', 'brief' ]: # Handle date formatter rather than date format style, dateformat = d_args[ 'dateformat'], None # Swap argument order style = style.replace( 'covasim', 'sciris' ) # In case any users are confused about what "default" is else: dateformat, style = d_args[ 'dateformat'], 'sciris' # Otherwise, treat dateformat as a date format sc.dateformatter( ax=ax, style=style, dateformat=dateformat, **date_args) # Actually format the axis with dates, rotation, etc. else: # Handle start and end days xmin, xmax = ax.get_xlim() if date_args.start: xmin = float( sc.day(date_args.start, start_date=start_day)) # Keep original type (float) if date_args.end: xmax = float(sc.day(date_args.end, start_date=start_day)) ax.set_xlim([xmin, xmax]) # Set the x-axis intervals if date_args.interval: ax.set_xticks(np.arange(xmin, xmax + 1, date_args.interval)) # Restore date args date_args.update(d_args) return
def day(self, day, *args): ''' Convert a string, date/datetime object, or int to a day (int). Args: day (str, date, int, or list): convert any of these objects to a day relative to the simulation's start day Returns: days (int or str): the day(s) in simulation time **Example**:: sim.day('2020-04-05') # Returns 35 ''' return sc.day(day, *args, start_day=self['start_day'])
def date_formatter(start_day=None, dateformat=None, interval=None, start=None, end=None, ax=None, sim=None): ''' Create an automatic date formatter based on a number of days and a start day. Wrapper for Matplotlib's date formatter. Note, start_day is not required if the axis uses dates already. To be used in conjunction with setting the x-axis tick label formatter. Args: start_day (str/date): the start day, either as a string or date object dateformat (str): the date format (default '%b-%d') interval (int): if supplied, the interval between ticks (must supply an axis also to take effect) start (str/int): if supplied, the lower limit of the axis end (str/int): if supplied, the upper limit of the axis ax (axes): if supplied, automatically set the x-axis formatter for this axis sim (Sim): if supplied, get the start day from this **Examples**:: # Automatically configure the axis with default option cv.date_formatter(sim=sim, ax=ax) # Manually configure ax = pl.subplot(111) ax.plot(np.arange(60), np.random.random(60)) formatter = cv.date_formatter(start_day='2020-04-04', interval=7, start='2020-05-01', end=50, dateformat='%Y-%m-%d', ax=ax) ax.xaxis.set_major_formatter(formatter) ''' # Set the default -- "Mar-01" if dateformat is None: dateformat = '%b-%d' # Convert to a date object if start_day is None and sim is not None: start_day = sim['start_day'] if start_day is None: errormsg = 'If not supplying a start day, you must supply a sim object' raise ValueError(errormsg) start_day = sc.date(start_day) @ticker.FuncFormatter def mpl_formatter(x, pos): return (start_day + dt.timedelta(days=int(x))).strftime(dateformat) # Set initial tick marks (intervals and limits) if ax is not None: # Handle limits xmin, xmax = ax.get_xlim() if start: xmin = sc.day(start, start_day=start_day) if end: xmax = sc.day(end, start_day=start_day) ax.set_xlim((xmin, xmax)) # Set the x-axis intervals if interval: ax.set_xticks(np.arange(xmin, xmax + 1, interval)) # Set the formatter ax.xaxis.set_major_formatter(mpl_formatter) return mpl_formatter