Skip to content

Commit 7240b87

Browse files
author
Chang She
committed
TST: additional coverage and cruft removal for ts plotting pandas-dev#1245
1 parent 9bfdc3c commit 7240b87

File tree

2 files changed

+115
-185
lines changed

2 files changed

+115
-185
lines changed

pandas/tseries/plotting.py

+15-184
Original file line numberDiff line numberDiff line change
@@ -25,41 +25,12 @@
2525

2626
import warnings
2727

28-
#----------------------------------------------------------------------
29-
# Generic documentation
30-
31-
_doc_parameters = dict(
32-
figsize="""figsize : {None, tuple}
33-
Size of the figure, as a tuple (width, height) in inches.
34-
If None, defaults to rc figure.figsize.""",
35-
dpi="""dpi : {None, int}, optional
36-
Resolution in dots per inches.
37-
If None, defaults to rc figure.dpi.""",
38-
facecolor="""facecolor : {None, string}, optional
39-
Background color.
40-
If None, defaults to rc figure.facecolor.""",
41-
edgecolor="""edgecolor : {None, string}, optional
42-
Border color.
43-
If None, defaults to rc figure.edgecolor.""",
44-
linewidth="""linewidth : {float, None}
45-
Width of the patch edge line.""",
46-
frameon="""frameon : {True, False}
47-
Whether to draw the frame around the figure.""",
48-
subplotpars="""subplotpars : {None, var}
49-
A :class:`SubplotParams` instance, defaults to rc""",
50-
mandatoryplotargs="""args : var
51-
Mandatory arguments for the creation of the subplot.
52-
These arguments should be given as ``nb_of_rows``, ``nb_of_columns``,
53-
``plot_number``, or as a single 3-digit number if the 3 previous numbers
54-
are all lower than 10.""" )
55-
56-
5728
#----------------------------------------------------------------------
5829
# Plotting functions and monkey patches
5930

60-
def tsplot(series, plotf, *args, **kwargs):
31+
def tsplot(series, plotf, **kwargs):
6132
"""
62-
Plots a Series on the given Matplotlib axes object
33+
Plots a Series on the given Matplotlib axes or the current axes
6334
6435
Parameters
6536
----------
@@ -68,7 +39,7 @@ def tsplot(series, plotf, *args, **kwargs):
6839
6940
Notes
7041
_____
71-
Supports same args and kwargs as Axes.plot
42+
Supports same kwargs as Axes.plot
7243
7344
"""
7445
# Used inferred freq is possible, need a test case for inferred
@@ -86,15 +57,6 @@ def tsplot(series, plotf, *args, **kwargs):
8657
if isinstance(series.index, DatetimeIndex):
8758
series = series.to_period(freq=freq)
8859

89-
if not isinstance(series.index, PeriodIndex):
90-
#try to get it to DatetimeIndex then to period
91-
if series.index.inferred_type == 'datetime':
92-
idx = DatetimeIndex(series.index).to_period(freq=freq)
93-
series = Series(series.values, idx, name=series.name)
94-
else:
95-
raise TypeError('series argument to tsplot must have '
96-
'DatetimeIndex or PeriodIndex')
97-
9860
if freq != series.index.freq:
9961
series = series.asfreq(freq)
10062

@@ -103,6 +65,7 @@ def tsplot(series, plotf, *args, **kwargs):
10365
if 'ax' in kwargs:
10466
ax = kwargs.pop('ax')
10567
else:
68+
import matplotlib.pyplot as plt
10669
ax = plt.gca()
10770

10871
# Specialized ts plotting attributes for Axes
@@ -119,29 +82,22 @@ def tsplot(series, plotf, *args, **kwargs):
11982
if mask.any():
12083
masked_array = np.ma.array(series.values)
12184
masked_array = np.ma.masked_where(mask, masked_array)
122-
args = _check_plot_params(masked_array, series.index, freq, style,
123-
*args)
85+
args = [series.index, masked_array]
12486
else:
125-
args = _check_plot_params(series, series.index, freq, style, *args)
87+
args = [series.index, series]
12688

127-
plotted = plotf(ax, *args, **kwargs)
89+
if style is not None:
90+
args.append(style)
12891

129-
format_dateaxis(ax, ax.freq)
92+
plotf(ax, *args, **kwargs)
13093

131-
# when adding a right axis (using add_yaxis), for some reason the
132-
# x axis limits don't get properly set. This gets around the problem
133-
xlim = ax.get_xlim()
134-
if xlim[0] == 0.0 and xlim[1] == 1.0:
135-
# if xlim still at default values, autoscale the axis
136-
ax.autoscale_view()
94+
format_dateaxis(ax, ax.freq)
13795

13896
left = series.index[0] #get_datevalue(series.index[0], freq)
13997
right = series.index[-1] #get_datevalue(series.index[-1], freq)
14098
ax.set_xlim(left, right)
14199

142-
return plotted
143-
144-
tsplot.__doc__ %= _doc_parameters
100+
return ax
145101

146102
def get_datevalue(date, freq):
147103
if isinstance(date, Period):
@@ -155,112 +111,6 @@ def get_datevalue(date, freq):
155111
return None
156112
raise ValueError("Unrecognizable date '%s'" % date)
157113

158-
159-
# Check and format plotting parameters
160-
161-
def _check_plot_params(series, xdata, freq, style, *args):
162-
"""
163-
Defines the plot coordinates (and basic plotting arguments).
164-
"""
165-
remaining = list(args)
166-
noinfo_msg = "No date information available!"
167-
168-
# No args ? Use defaults, if any
169-
if len(args) == 0:
170-
if xdata is None:
171-
raise ValueError(noinfo_msg)
172-
if style is not None:
173-
return (xdata, series, style)
174-
else:
175-
return (xdata, series)
176-
177-
output = []
178-
while len(remaining) > 0:
179-
a = remaining.pop(0)
180-
output.extend(_handle_param(a, remaining, series, xdata, freq))
181-
182-
# Reinitialize the plot if needed ...........
183-
if xdata is None:
184-
xdata = output[0]
185-
186-
# Force the xdata to the current frequency
187-
elif output[0].freq != freq:
188-
output = list(output)
189-
output[0] = output[0].asfreq(freq)
190-
191-
return output
192-
193-
def _handle_param(curr, remaining, series, xdata, freq):
194-
# The argument is a format: use default dates/
195-
noinfo_msg = "No date information available!"
196-
if isinstance(curr, str):
197-
if xdata is None:
198-
raise ValueError(noinfo_msg)
199-
else:
200-
return [xdata, series, curr]
201-
202-
# The argument is a Series: use its dates for x
203-
elif isinstance(curr, Series):
204-
(x, y) = (curr.index, curr.values)
205-
if len(remaining) > 0 and isinstance(remaining[0], str):
206-
b = remaining.pop(0)
207-
return [x, y, b]
208-
else:
209-
return [x, y]
210-
211-
# The argument is a PeriodIndex............
212-
elif isinstance(curr, PeriodIndex):
213-
return _handle_period_index(curr, remaining, series, xdata, freq)
214-
215-
# Otherwise..............................
216-
elif len(remaining) > 0 and isinstance(remaining[0], str):
217-
b = remaining.pop(0)
218-
if xdata is None:
219-
raise ValueError(noinfo_msg)
220-
else:
221-
return [xdata, curr, b]
222-
elif xdata is None:
223-
raise ValueError(noinfo_msg)
224-
else:
225-
return [xdata, curr]
226-
227-
def _handle_period_index(curr, remaining, series, xdata, freq):
228-
# Force to current freq
229-
noinfo_msg = "No date information available!"
230-
if freq is not None:
231-
if curr.freq != freq:
232-
curr = curr.asfreq(freq)
233-
234-
# There's an argument after
235-
if len(remaining) > 0:
236-
#...and it's a format string
237-
if isinstance(remaining[0], str):
238-
b = remaining.pop(0)
239-
if series is None:
240-
raise ValueError(noinfo_msg)
241-
else:
242-
return [curr, series, b]
243-
244-
#... and it's another date: use the default
245-
elif isinstance(remaining[0], PeriodIndex):
246-
if series is None:
247-
raise ValueError(noinfo_msg)
248-
else:
249-
return [curr, series]
250-
251-
#... and it must be some data
252-
else:
253-
b = remaining.pop(0)
254-
if len(remaining) > 0:
255-
if isinstance(remaining[0], str):
256-
c = remaining.pop(0)
257-
return [curr, b, c]
258-
else:
259-
return [curr, b]
260-
else:
261-
if series is None:
262-
raise ValueError(noinfo_msg)
263-
264114
##### -------------------------------------------------------------------------
265115
#---- --- Locators ---
266116
##### -------------------------------------------------------------------------
@@ -302,7 +152,6 @@ def period_break(dates, period):
302152
previous = getattr(dates - 1, period)
303153
return (current - previous).nonzero()[0]
304154

305-
306155
def has_level_label(label_flags, vmin):
307156
"""
308157
Returns true if the ``label_flags`` indicate there is at least one label
@@ -318,7 +167,6 @@ def has_level_label(label_flags, vmin):
318167
else:
319168
return True
320169

321-
322170
def _daily_finder(vmin, vmax, freq):
323171
periodsperday = -1
324172

@@ -329,7 +177,7 @@ def _daily_finder(vmin, vmax, freq):
329177
periodsperday = 24 * 60
330178
elif freq == FreqGroup.FR_HR:
331179
periodsperday = 24
332-
else:
180+
else: # pragma: no cover
333181
raise ValueError("unexpected frequency: %s" % freq)
334182
periodsperyear = 365 * periodsperday
335183
periodspermonth = 28 * periodsperday
@@ -346,7 +194,7 @@ def _daily_finder(vmin, vmax, freq):
346194
elif freq == FreqGroup.FR_UND:
347195
periodsperyear = 100
348196
periodspermonth = 10
349-
else:
197+
else: # pragma: no cover
350198
raise ValueError("unexpected frequency")
351199

352200
# save this for later usage
@@ -377,7 +225,6 @@ def first_label(label_flags):
377225

378226
# Case 1. Less than a month
379227
if span <= periodspermonth:
380-
381228
day_start = period_break(dates_, 'day')
382229
month_start = period_break(dates_, 'month')
383230

@@ -528,11 +375,6 @@ def _second_finder(label_interval):
528375

529376

530377
def _monthly_finder(vmin, vmax, freq):
531-
if isinstance(freq, basestring):
532-
freq = frequencies.get_freq(freq)
533-
534-
if freq != FreqGroup.FR_MTH:
535-
raise ValueError("Unexpected frequency")
536378
periodsperyear = 12
537379

538380
vmin_orig = vmin
@@ -603,11 +445,6 @@ def _monthly_finder(vmin, vmax, freq):
603445

604446

605447
def _quarterly_finder(vmin, vmax, freq):
606-
if isinstance(freq, basestring):
607-
freq = frequencies.get_freq(freq)
608-
609-
if frequencies.get_freq_group(freq) != FreqGroup.FR_QTR:
610-
raise ValueError("Unexpected frequency")
611448
periodsperyear = 4
612449
vmin_orig = vmin
613450
(vmin, vmax) = (int(vmin), int(vmax))
@@ -653,10 +490,6 @@ def _quarterly_finder(vmin, vmax, freq):
653490
return info
654491

655492
def _annual_finder(vmin, vmax, freq):
656-
if isinstance(freq, basestring):
657-
freq = frequencies.get_freq(freq)
658-
if frequencies.get_freq_group(freq) != FreqGroup.FR_ANN:
659-
raise ValueError("Unexpected frequency")
660493
(vmin, vmax) = (int(vmin), int(vmax + 1))
661494
span = vmax - vmin + 1
662495
#..............
@@ -675,7 +508,6 @@ def _annual_finder(vmin, vmax, freq):
675508
#..............
676509
return info
677510

678-
679511
def get_finder(freq):
680512
if isinstance(freq, basestring):
681513
freq = frequencies.get_freq(freq)
@@ -690,7 +522,7 @@ def get_finder(freq):
690522
elif ((freq >= FreqGroup.FR_BUS) or (freq == FreqGroup.FR_UND) or
691523
fgroup == FreqGroup.FR_WK):
692524
return _daily_finder
693-
else:
525+
else: # pragma: no cover
694526
errmsg = "Unsupported frequency: %s" % (freq)
695527
raise NotImplementedError(errmsg)
696528

@@ -749,7 +581,7 @@ def __call__(self):
749581
vmin, vmax = vmax, vmin
750582
if self.isdynamic:
751583
locs = self._get_default_locs(vmin, vmax)
752-
else:
584+
else: # pragma: no cover
753585
base = self.base
754586
(d, m) = divmod(vmin, base)
755587
vmin = (d + 1) * base
@@ -870,7 +702,6 @@ def format_dateaxis(subplot, freq):
870702
subplot.xaxis.set_minor_formatter(minformatter)
871703
pylab.draw_if_interactive()
872704

873-
874705
class DateConverter(object):
875706

876707
@classmethod

0 commit comments

Comments
 (0)