def _get_freq(ax, series): # get frequency from data freq = getattr(series.index, 'freq', None) if freq is None: freq = getattr(series.index, 'inferred_freq', None) ax_freq = getattr(ax, 'freq', None) if ax_freq is None: if hasattr(ax, 'left_ax'): ax_freq = getattr(ax.left_ax, 'freq', None) elif hasattr(ax, 'right_ax'): ax_freq = getattr(ax.right_ax, 'freq', None) # use axes freq if no data freq if freq is None: freq = ax_freq # get the period frequency if isinstance(freq, DateOffset): freq = freq.rule_code else: freq = frequencies.get_base_alias(freq) freq = frequencies.get_period_alias(freq) return freq, ax_freq
def _maybe_convert_timedelta(self, other): if isinstance( other, (timedelta, np.timedelta64, offsets.Tick, np.ndarray)): offset = frequencies.to_offset(self.freq.rule_code) if isinstance(offset, offsets.Tick): if isinstance(other, np.ndarray): nanos = np.vectorize(delta_to_nanoseconds)(other) else: nanos = delta_to_nanoseconds(other) offset_nanos = delta_to_nanoseconds(offset) check = np.all(nanos % offset_nanos == 0) if check: return nanos // offset_nanos elif isinstance(other, offsets.DateOffset): freqstr = other.rule_code base = frequencies.get_base_alias(freqstr) if base == self.freq.rule_code: return other.n msg = _DIFFERENT_FREQ_INDEX.format(self.freqstr, other.freqstr) raise IncompatibleFrequency(msg) elif is_integer(other): # integer is passed to .shift via # _add_datetimelike_methods basically # but ufunc may pass integer to _add_delta return other # raise when input doesn't have freq msg = "Input has different freq from PeriodIndex(freq={0})" raise IncompatibleFrequency(msg.format(self.freqstr))
def _maybe_convert_timedelta(self, other): if isinstance(other, (timedelta, np.timedelta64, offsets.Tick, Timedelta)): offset = frequencies.to_offset(self.freq.rule_code) if isinstance(offset, offsets.Tick): nanos = tslib._delta_to_nanoseconds(other) offset_nanos = tslib._delta_to_nanoseconds(offset) if nanos % offset_nanos == 0: return nanos // offset_nanos elif isinstance(other, offsets.DateOffset): freqstr = frequencies.get_standard_freq(other) base = frequencies.get_base_alias(freqstr) if base == self.freq.rule_code: return other.n elif isinstance(other, np.ndarray): if com.is_integer_dtype(other): return other elif com.is_timedelta64_dtype(other): offset = frequencies.to_offset(self.freq) if isinstance(offset, offsets.Tick): nanos = tslib._delta_to_nanoseconds(other) offset_nanos = tslib._delta_to_nanoseconds(offset) if (nanos % offset_nanos).all() == 0: return nanos // offset_nanos msg = "Input has different freq from PeriodIndex(freq={0})" raise ValueError(msg.format(self.freqstr))
def _is_dynamic_freq(self, freq): if isinstance(freq, DateOffset): freq = freq.rule_code else: freq = get_base_alias(freq) freq = get_period_alias(freq) return freq is not None
def _maybe_convert_timedelta(self, other): if isinstance(other, (timedelta, np.timedelta64, offsets.Tick, Timedelta)): offset = frequencies.to_offset(self.freq.rule_code) if isinstance(offset, offsets.Tick): nanos = tslib._delta_to_nanoseconds(other) offset_nanos = tslib._delta_to_nanoseconds(offset) if nanos % offset_nanos == 0: return nanos // offset_nanos elif isinstance(other, offsets.DateOffset): freqstr = other.rule_code base = frequencies.get_base_alias(freqstr) if base == self.freq.rule_code: return other.n msg = _DIFFERENT_FREQ_INDEX.format(self.freqstr, other.freqstr) raise IncompatibleFrequency(msg) elif isinstance(other, np.ndarray): if is_integer_dtype(other): return other elif is_timedelta64_dtype(other): offset = frequencies.to_offset(self.freq) if isinstance(offset, offsets.Tick): nanos = tslib._delta_to_nanoseconds(other) offset_nanos = tslib._delta_to_nanoseconds(offset) if (nanos % offset_nanos).all() == 0: return nanos // offset_nanos # raise when input doesn't have freq msg = "Input has different freq from PeriodIndex(freq={0})" raise IncompatibleFrequency(msg.format(self.freqstr))
def _add_offset(self, other): assert not isinstance(other, Tick) base = frequencies.get_base_alias(other.rule_code) if base != self.freq.rule_code: msg = DIFFERENT_FREQ_INDEX.format(self.freqstr, other.freqstr) raise IncompatibleFrequency(msg) return self.shift(other.n)
def _use_dynamic_x(ax, data): freq = _get_index_freq(data) ax_freq = _get_ax_freq(ax) if freq is None: # convert irregular if axes has freq info freq = ax_freq else: # do not use tsplot if irregular was plotted first if (ax_freq is None) and (len(ax.get_lines()) > 0): return False if freq is None: return False if isinstance(freq, DateOffset): freq = freq.rule_code else: freq = frequencies.get_base_alias(freq) freq = frequencies.get_period_alias(freq) if freq is None: return False # hack this for 0.10.1, creating more technical debt...sigh if isinstance(data.index, ABCDatetimeIndex): base = frequencies.get_freq(freq) x = data.index if (base <= frequencies.FreqGroup.FR_DAY): return x[:1].is_normalized return Period(x[0], freq).to_timestamp(tz=x.tz) == x[0] return True
def _add_offset(self, other): assert not isinstance(other, Tick) base = frequencies.get_base_alias(other.rule_code) if base != self.freq.rule_code: _raise_on_incompatible(self, other) # Note: when calling parent class's _add_timedeltalike_scalar, # it will call delta_to_nanoseconds(delta). Because delta here # is an integer, delta_to_nanoseconds will return it unchanged. result = super(PeriodArray, self)._add_timedeltalike_scalar(other.n) return type(self)(result, freq=self.freq)
def _add_delta(self, other): if isinstance(other, (timedelta, np.timedelta64, offsets.Tick, Timedelta)): offset = frequencies.to_offset(self.freq) if isinstance(offset, offsets.Tick): nanos = tslib._delta_to_nanoseconds(other) offset_nanos = tslib._delta_to_nanoseconds(offset) if nanos % offset_nanos == 0: return self.shift(nanos // offset_nanos) elif isinstance(other, offsets.DateOffset): freqstr = frequencies.get_standard_freq(other) base = frequencies.get_base_alias(freqstr) if base == self.freq: return self.shift(other.n) raise ValueError("Input has different freq from PeriodIndex(freq={0})".format(self.freq))
def _maybe_convert_timedelta(self, other): """ Convert timedelta-like input to an integer multiple of self.freq Parameters ---------- other : timedelta, np.timedelta64, DateOffset, int, np.ndarray Returns ------- converted : int, np.ndarray[int64] Raises ------ IncompatibleFrequency : if the input cannot be written as a multiple of self.freq. Note IncompatibleFrequency subclasses ValueError. """ if isinstance( other, (timedelta, np.timedelta64, Tick, np.ndarray)): offset = frequencies.to_offset(self.freq.rule_code) if isinstance(offset, Tick): if isinstance(other, np.ndarray): nanos = np.vectorize(delta_to_nanoseconds)(other) else: nanos = delta_to_nanoseconds(other) offset_nanos = delta_to_nanoseconds(offset) check = np.all(nanos % offset_nanos == 0) if check: return nanos // offset_nanos elif isinstance(other, DateOffset): freqstr = other.rule_code base = frequencies.get_base_alias(freqstr) if base == self.freq.rule_code: return other.n msg = DIFFERENT_FREQ_INDEX.format(self.freqstr, other.freqstr) raise IncompatibleFrequency(msg) elif lib.is_integer(other): # integer is passed to .shift via # _add_datetimelike_methods basically # but ufunc may pass integer to _add_delta return other # raise when input doesn't have freq msg = "Input has different freq from {cls}(freq={freqstr})" raise IncompatibleFrequency(msg.format(cls=type(self).__name__, freqstr=self.freqstr))
def _maybe_convert_timedelta(self, other): """ Convert timedelta-like input to an integer multiple of self.freq Parameters ---------- other : timedelta, np.timedelta64, DateOffset, int, np.ndarray Returns ------- converted : int, np.ndarray[int64] Raises ------ IncompatibleFrequency : if the input cannot be written as a multiple of self.freq. Note IncompatibleFrequency subclasses ValueError. """ if isinstance( other, (timedelta, np.timedelta64, Tick, np.ndarray)): offset = frequencies.to_offset(self.freq.rule_code) if isinstance(offset, Tick): # _check_timedeltalike_freq_compat will raise if incompatible delta = self._data._check_timedeltalike_freq_compat(other) return delta elif isinstance(other, DateOffset): freqstr = other.rule_code base = frequencies.get_base_alias(freqstr) if base == self.freq.rule_code: return other.n msg = DIFFERENT_FREQ.format(cls=type(self).__name__, own_freq=self.freqstr, other_freq=other.freqstr) raise IncompatibleFrequency(msg) elif is_integer(other): # integer is passed to .shift via # _add_datetimelike_methods basically # but ufunc may pass integer to _add_delta return other # raise when input doesn't have freq msg = DIFFERENT_FREQ.format(cls=type(self).__name__, own_freq=self.freqstr, other_freq=None) raise IncompatibleFrequency(msg)
def _maybe_convert_timedelta(self, other): """ Convert timedelta-like input to an integer multiple of self.freq Parameters ---------- other : timedelta, np.timedelta64, DateOffset, int, np.ndarray Returns ------- converted : int, np.ndarray[int64] Raises ------ IncompatibleFrequency : if the input cannot be written as a multiple of self.freq. Note IncompatibleFrequency subclasses ValueError. """ if isinstance(other, (timedelta, np.timedelta64, Tick, np.ndarray)): offset = frequencies.to_offset(self.freq.rule_code) if isinstance(offset, Tick): # _check_timedeltalike_freq_compat will raise if incompatible delta = self._data._check_timedeltalike_freq_compat(other) return delta elif isinstance(other, DateOffset): freqstr = other.rule_code base = frequencies.get_base_alias(freqstr) if base == self.freq.rule_code: return other.n msg = DIFFERENT_FREQ_INDEX.format(self.freqstr, other.freqstr) raise IncompatibleFrequency(msg) elif is_integer(other): # integer is passed to .shift via # _add_datetimelike_methods basically # but ufunc may pass integer to _add_delta return other # raise when input doesn't have freq msg = "Input has different freq from {cls}(freq={freqstr})" raise IncompatibleFrequency( msg.format(cls=type(self).__name__, freqstr=self.freqstr))
def _maybe_convert_index(ax, data): # tsplot converts automatically, but don't want to convert index # over and over for DataFrames if isinstance(data.index, ABCDatetimeIndex): freq = getattr(data.index, 'freq', None) if freq is None: freq = getattr(data.index, 'inferred_freq', None) if isinstance(freq, DateOffset): freq = freq.rule_code if freq is None: freq = _get_ax_freq(ax) if freq is None: raise ValueError('Could not get frequency alias for plotting') freq = frequencies.get_base_alias(freq) freq = frequencies.get_period_alias(freq) data = data.to_period(freq=freq) return data
def _maybe_convert_index(ax, data): # tsplot converts automatically, but don't want to convert index # over and over for DataFrames if isinstance(data.index, DatetimeIndex): freq = getattr(data.index, 'freq', None) if freq is None: freq = getattr(data.index, 'inferred_freq', None) if isinstance(freq, DateOffset): freq = freq.rule_code if freq is None: freq = _get_ax_freq(ax) if freq is None: raise ValueError('Could not get frequency alias for plotting') freq = frequencies.get_base_alias(freq) freq = frequencies.get_period_alias(freq) data = data.to_period(freq=freq) return data
def _maybe_convert_timedelta(self, other): if isinstance(other, (timedelta, np.timedelta64, offsets.Tick, np.ndarray)): offset = frequencies.to_offset(self.freq.rule_code) if isinstance(offset, offsets.Tick): if isinstance(other, np.ndarray): nanos = np.vectorize(delta_to_nanoseconds)(other) else: nanos = delta_to_nanoseconds(other) offset_nanos = delta_to_nanoseconds(offset) check = np.all(nanos % offset_nanos == 0) if check: return nanos // offset_nanos elif isinstance(other, offsets.DateOffset): freqstr = other.rule_code base = frequencies.get_base_alias(freqstr) if base == self.freq.rule_code: return other.n msg = _DIFFERENT_FREQ_INDEX.format(self.freqstr, other.freqstr) raise IncompatibleFrequency(msg) elif isinstance(other, np.ndarray): if is_integer_dtype(other): return other elif is_timedelta64_dtype(other): offset = frequencies.to_offset(self.freq) if isinstance(offset, offsets.Tick): nanos = delta_to_nanoseconds(other) offset_nanos = delta_to_nanoseconds(offset) if (nanos % offset_nanos).all() == 0: return nanos // offset_nanos elif is_integer(other): # integer is passed to .shift via # _add_datetimelike_methods basically # but ufunc may pass integer to _add_delta return other # raise when input doesn't have freq msg = "Input has different freq from PeriodIndex(freq={0})" raise IncompatibleFrequency(msg.format(self.freqstr))
def tsplot(series, plotf, *args, **kwargs): """ Plots a Series on the given Matplotlib axes object Parameters ---------- axes : Axes series : Series Notes _____ Supports same args and kwargs as Axes.plot """ # Used inferred freq is possible, need a test case for inferred freq = getattr(series.index, 'freq', None) if freq is None and hasattr(series.index, 'inferred_freq'): freq = series.index.inferred_freq if isinstance(freq, DateOffset): freq = freq.rule_code else: freq = frequencies.get_base_alias(freq) freq = frequencies.to_calendar_freq(freq) # Convert DatetimeIndex to PeriodIndex if isinstance(series.index, DatetimeIndex): idx = series.index.to_period(freq=freq) series = Series(series.values, idx, name=series.name) if not isinstance(series.index, PeriodIndex): #try to get it to DatetimeIndex then to period if series.index.inferred_type == 'datetime': idx = DatetimeIndex(series.index).to_period(freq=freq) series = Series(series.values, idx, name=series.name) else: raise TypeError('series argument to tsplot must have ' 'DatetimeIndex or PeriodIndex') if freq != series.index.freq: series = series.asfreq(freq) series = series.dropna() if 'ax' in kwargs: ax = kwargs.pop('ax') else: ax = plt.gca() # Specialized ts plotting attributes for Axes ax.freq = freq xaxis = ax.get_xaxis() xaxis.freq = freq xaxis.converter = DateConverter ax.legendlabels = [kwargs.get('label', None)] ax.view_interval = None ax.date_axis_info = None # format args and lot args = _check_plot_params(series, series.index, freq, *args) plotted = plotf(ax, *args, **kwargs) format_dateaxis(ax, ax.freq) # when adding a right axis (using add_yaxis), for some reason the # x axis limits don't get properly set. This gets around the problem xlim = ax.get_xlim() if xlim[0] == 0.0 and xlim[1] == 1.0: # if xlim still at default values, autoscale the axis ax.autoscale_view() left = series.index[0] #get_datevalue(series.index[0], freq) right = series.index[-1] #get_datevalue(series.index[-1], freq) ax.set_xlim(left, right) return plotted
def tsplot(series, plotf, **kwargs): """ Plots a Series on the given Matplotlib axes or the current axes Parameters ---------- axes : Axes series : Series Notes _____ Supports same kwargs as Axes.plot """ # Used inferred freq is possible, need a test case for inferred freq = getattr(series.index, 'freq', None) if freq is None and hasattr(series.index, 'inferred_freq'): freq = series.index.inferred_freq if isinstance(freq, DateOffset): freq = freq.rule_code else: freq = frequencies.get_base_alias(freq) freq = frequencies.get_period_alias(freq) # Convert DatetimeIndex to PeriodIndex if isinstance(series.index, DatetimeIndex): series = series.to_period(freq=freq) if freq != series.index.freq: series = series.asfreq(freq) style = kwargs.pop('style', None) if 'ax' in kwargs: ax = kwargs.pop('ax') else: import matplotlib.pyplot as plt ax = plt.gca() # Specialized ts plotting attributes for Axes ax.freq = freq xaxis = ax.get_xaxis() xaxis.freq = freq xaxis.converter = DateConverter ax.legendlabels = [kwargs.get('label', None)] ax.view_interval = None ax.date_axis_info = None # format args and lot mask = isnull(series) if mask.any(): masked_array = np.ma.array(series.values) masked_array = np.ma.masked_where(mask, masked_array) args = [series.index, masked_array] else: args = [series.index, series] if style is not None: args.append(style) plotf(ax, *args, **kwargs) format_dateaxis(ax, ax.freq) left = series.index[0] #get_datevalue(series.index[0], freq) right = series.index[-1] #get_datevalue(series.index[-1], freq) ax.set_xlim(left, right) return ax
def tsplot(series, plotf, *args, **kwargs): """ Plots a Series on the given Matplotlib axes object Parameters ---------- axes : Axes series : Series Notes _____ Supports same args and kwargs as Axes.plot """ # Used inferred freq is possible, need a test case for inferred freq = getattr(series.index, 'freq', None) if freq is None and hasattr(series.index, 'inferred_freq'): freq = series.index.inferred_freq if isinstance(freq, DateOffset): freq = freq.rule_code else: freq = frequencies.get_base_alias(freq) freq = frequencies.to_calendar_freq(freq) # Convert DatetimeIndex to PeriodIndex if isinstance(series.index, DatetimeIndex): idx = series.index.to_period(freq=freq) series = Series(series.values, idx, name=series.name) if not isinstance(series.index, PeriodIndex): #try to get it to DatetimeIndex then to period if series.index.inferred_type == 'datetime': idx = DatetimeIndex(series.index).to_period(freq=freq) series = Series(series.values, idx, name=series.name) else: raise TypeError('series argument to tsplot must have ' 'DatetimeIndex or PeriodIndex') if freq != series.index.freq: series = series.asfreq(freq) series = series.dropna() style = kwargs.pop('style', None) if 'ax' in kwargs: ax = kwargs.pop('ax') else: ax = plt.gca() # Specialized ts plotting attributes for Axes ax.freq = freq xaxis = ax.get_xaxis() xaxis.freq = freq xaxis.converter = DateConverter ax.legendlabels = [kwargs.get('label', None)] ax.view_interval = None ax.date_axis_info = None # format args and lot args = _check_plot_params(series, series.index, freq, style, *args) plotted = plotf(ax, *args, **kwargs) format_dateaxis(ax, ax.freq) # when adding a right axis (using add_yaxis), for some reason the # x axis limits don't get properly set. This gets around the problem xlim = ax.get_xlim() if xlim[0] == 0.0 and xlim[1] == 1.0: # if xlim still at default values, autoscale the axis ax.autoscale_view() left = series.index[0] #get_datevalue(series.index[0], freq) right = series.index[-1] #get_datevalue(series.index[-1], freq) ax.set_xlim(left, right) return plotted