Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4f33c14

Browse files
author
Chang She
committedMay 29, 2012
BUG: set_xlim for time series plots #1339
1 parent b8b3edc commit 4f33c14

File tree

2 files changed

+45
-36
lines changed

2 files changed

+45
-36
lines changed
 

‎pandas/tseries/plotting.py

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"""
44

55
#!!! TODO: Use the fact that axis can have units to simplify the process
6-
6+
import datetime as pydt
7+
from datetime import datetime
78

89
from matplotlib import pylab
910
from matplotlib.ticker import Formatter, Locator
@@ -17,6 +18,7 @@
1718

1819
from pandas.tseries.period import Period, PeriodIndex
1920
from pandas.tseries.index import DatetimeIndex
21+
from pandas.core.index import Index
2022
from pandas.core.series import Series
2123

2224
import warnings
@@ -102,6 +104,9 @@ def tsplot(series, plotf, *args, **kwargs):
102104

103105
# Specialized ts plotting attributes for Axes
104106
ax.freq = freq
107+
xaxis = ax.get_xaxis()
108+
xaxis.freq = freq
109+
xaxis.converter = DateConverter
105110
ax.legendlabels = [kwargs.get('label', None)]
106111
ax.view_interval = None
107112
ax.date_axis_info = None
@@ -119,8 +124,8 @@ def tsplot(series, plotf, *args, **kwargs):
119124
# if xlim still at default values, autoscale the axis
120125
ax.autoscale_view()
121126

122-
left = get_datevalue(series.index[0], freq)
123-
right = get_datevalue(series.index[-1], freq)
127+
left = series.index[0] #get_datevalue(series.index[0], freq)
128+
right = series.index[-1] #get_datevalue(series.index[-1], freq)
124129
ax.set_xlim(left, right)
125130

126131
return plotted
@@ -130,7 +135,7 @@ def tsplot(series, plotf, *args, **kwargs):
130135
def get_datevalue(date, freq):
131136
if isinstance(date, Period):
132137
return date.asfreq(freq).ordinal
133-
elif isinstance(date, str):
138+
elif isinstance(date, (str, datetime, pydt.date, pydt.time)):
134139
return Period(date, freq).ordinal
135140
elif isinstance(date, (int, float)) or \
136141
(isinstance(date, np.ndarray) and (date.size == 1)):
@@ -929,35 +934,12 @@ def add_yaxis(fsp=None, position='right', yscale=None, basey=10, subsy=None):
929934
pylab.draw_if_interactive()
930935
return fsp_alt
931936

932-
def set_dlim(subplot, start_date=None, end_date=None):
933-
"""
934-
Sets the date limits of the plot to ``start_date`` and ``end_date``.
935-
The dates can be given as :class:`~Period` objects, strings or
936-
integers.
937+
class DateConverter(object):
937938

938-
Parameters
939-
----------
940-
start_date : {var}
941-
Starting date of the plot. If None, the current left limit
942-
(earliest date) is used.
943-
end_date : {var}
944-
Ending date of the plot. If None, the current right limit (latest
945-
date) is used.
946-
"""
947-
freq = getattr(subplot, 'freq', None)
948-
if freq is None:
949-
raise ValueError("Undefined frequency! Date limits can't be set!")
950-
xleft = get_datevalue(start_date, freq)
951-
xright = get_datevalue(end_date, freq)
952-
subplot.set_xlim(xleft, xright)
953-
return (xleft, xright)
954-
955-
def get_dlim(subplot):
956-
"""
957-
Returns the limits of the x axis as a :class:`~PeriodIndex`.
958-
"""
959-
freq = getattr(subplot, 'freq', None)
960-
xlims = subplot.get_xlim()
961-
if freq is None:
962-
return xlims
963-
return PeriodIndex(xlims, freq=freq)
939+
@classmethod
940+
def convert(cls, values, units, axis):
941+
if isinstance(values, (int, float, str, datetime, Period)):
942+
return get_datevalue(values, axis.freq)
943+
if isinstance(values, Index):
944+
return values.map(lambda x: get_datevalue(x, axis.freq))
945+
return map(lambda x: get_datevalue(x, axis.freq), values)

‎pandas/tseries/tests/test_plotting.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from pandas.tseries.index import date_range
1313
from pandas.tseries.offsets import Minute, DateOffset
14-
from pandas.tseries.period import period_range
14+
from pandas.tseries.period import period_range, Period
1515
from pandas.tseries.resample import DatetimeIndex, TimeGrouper
1616
import pandas.tseries.offsets as offsets
1717
import pandas.tseries.frequencies as frequencies
@@ -133,6 +133,33 @@ def test_dataframe(self):
133133
idx = ax.get_lines()[0].get_xdata()
134134
self.assert_(idx.freqstr == 'D')
135135

136+
@slow
137+
def test_set_xlim(self):
138+
ser = tm.makeTimeSeries()
139+
ax = ser.plot()
140+
xlim = ax.get_xlim()
141+
ax.set_xlim(xlim[0] - 5, xlim[1] + 10)
142+
ax.get_figure().canvas.draw()
143+
result = ax.get_xlim()
144+
self.assertEqual(result[0], xlim[0] - 5)
145+
self.assertEqual(result[1], xlim[1] + 10)
146+
147+
# string
148+
expected = (Period('1/1/2000', ax.freq), Period('4/1/2000', ax.freq))
149+
ax.set_xlim('1/1/2000', '4/1/2000')
150+
ax.get_figure().canvas.draw()
151+
result = ax.get_xlim()
152+
self.assertEqual(int(result[0]), expected[0].ordinal)
153+
self.assertEqual(int(result[1]), expected[1].ordinal)
154+
155+
# datetim
156+
expected = (Period('1/1/2000', ax.freq), Period('4/1/2000', ax.freq))
157+
ax.set_xlim(datetime(2000, 1, 1), datetime(2000, 4, 1))
158+
ax.get_figure().canvas.draw()
159+
result = ax.get_xlim()
160+
self.assertEqual(int(result[0]), expected[0].ordinal)
161+
self.assertEqual(int(result[1]), expected[1].ordinal)
162+
136163
PNG_PATH = 'tmp.png'
137164
def _check_plot_works(f, freq=None, series=None, *args, **kwargs):
138165
import matplotlib.pyplot as plt

0 commit comments

Comments
 (0)
Please sign in to comment.