We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Matplotlib cursor position wrong after using asfreq method to change freq of DateTimeIndex from None to something
After using the `asfreq` method to change the frequency of a time-series DataFrame from `None` to something e.g. `15Min` the cursor position in matplotlib graphs of that DataFrame is no longer correct (usually shows a datetime just after the unix epoch).  The following demonstrates this (NB dt in df1 is not a constant):

```
df1 = pandas.read_csv('tseries1.csv', names=['tstamp', 'Q'], parse_dates=True, 
    index_col='tstamp').clip_lower(0).fillna(0)
df1['T'] = pandas.read_csv('tseries2.csv', names=['tstamp', 'T'], parse_dates=True, 
    index_col='tstamp', squeeze=True).clip_lower(0).fillna(0)

df2 = df1.asfreq(freq='15Min', method='ffill')
# NB df1.index.freq is None
# NB df2.index.freq is <15 * Minutes>
df1.plot()
df2.plot()
plt.show()
```

I find the Matplotlib cursor position to be invaluable when looking for features in very long time-series.

Versions:
- pandas master (commit ID 764b444)
- numpy 1.8
- matplotlib 1.3.0

Matplotlib cursor position wrong after using asfreq method to change freq of DateTimeIndex from None to something
After using the `asfreq` method to change the frequency of a time-series DataFrame from `None` to something e.g. `15Min` the cursor position in matplotlib graphs of that DataFrame is no longer correct (usually shows a datetime just after the unix epoch).  The following demonstrates this (NB dt in df1 is not a constant):

```
df1 = pandas.read_csv('tseries1.csv', names=['tstamp', 'Q'], parse_dates=True, 
    index_col='tstamp').clip_lower(0).fillna(0)
df1['T'] = pandas.read_csv('tseries2.csv', names=['tstamp', 'T'], parse_dates=True, 
    index_col='tstamp', squeeze=True).clip_lower(0).fillna(0)

df2 = df1.asfreq(freq='15Min', method='ffill')
# NB df1.index.freq is None
# NB df2.index.freq is <15 * Minutes>
df1.plot()
df2.plot()
plt.show()
```

I find the Matplotlib cursor position to be invaluable when looking for features in very long time-series.

Versions:
- pandas master (commit ID 764b444)
- numpy 1.8
- matplotlib 1.3.0


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pandas/tseries/plotting.py`
Content:
```
1 """
2 Period formatters and locators adapted from scikits.timeseries by
3 Pierre GF Gerard-Marchant & Matt Knox
4 """
5 
6 #!!! TODO: Use the fact that axis can have units to simplify the process
7 import datetime as pydt
8 from datetime import datetime
9 
10 from matplotlib import pylab
11 import matplotlib.units as units
12 
13 import numpy as np
14 
15 from pandas import isnull
16 from pandas.tseries.period import Period
17 from pandas.tseries.offsets import DateOffset
18 import pandas.tseries.frequencies as frequencies
19 from pandas.tseries.index import DatetimeIndex
20 import pandas.core.common as com
21 
22 from pandas.tseries.converter import (PeriodConverter, TimeSeries_DateLocator,
23                                       TimeSeries_DateFormatter)
24 
25 #----------------------------------------------------------------------
26 # Plotting functions and monkey patches
27 
28 
29 def tsplot(series, plotf, **kwargs):
30     """
31     Plots a Series on the given Matplotlib axes or the current axes
32 
33     Parameters
34     ----------
35     axes : Axes
36     series : Series
37 
38     Notes
39     _____
40     Supports same kwargs as Axes.plot
41 
42     """
43     # Used inferred freq is possible, need a test case for inferred
44     if 'ax' in kwargs:
45         ax = kwargs.pop('ax')
46     else:
47         import matplotlib.pyplot as plt
48         ax = plt.gca()
49 
50     freq = _get_freq(ax, series)
51     # resample against axes freq if necessary
52     if freq is None:  # pragma: no cover
53         raise ValueError('Cannot use dynamic axis without frequency info')
54     else:
55         # Convert DatetimeIndex to PeriodIndex
56         if isinstance(series.index, DatetimeIndex):
57             series = series.to_period(freq=freq)
58         freq, ax_freq, series = _maybe_resample(series, ax, freq, plotf,
59                                                 kwargs)
60 
61     # Set ax with freq info
62     _decorate_axes(ax, freq, kwargs)
63 
64     # mask missing values
65     args = _maybe_mask(series)
66 
67     # how to make sure ax.clear() flows through?
68     if not hasattr(ax, '_plot_data'):
69         ax._plot_data = []
70     ax._plot_data.append((series, kwargs))
71 
72     # styles
73     style = kwargs.pop('style', None)
74     if style is not None:
75         args.append(style)
76 
77     lines = plotf(ax, *args, **kwargs)
78     label = kwargs.get('label', None)
79 
80     # set date formatter, locators and rescale limits
81     format_dateaxis(ax, ax.freq)
82     left, right = _get_xlim(ax.get_lines())
83     ax.set_xlim(left, right)
84 
85     # x and y coord info
86     tz = series.index.to_datetime().tz
87     ax.format_coord = lambda t, y : "t = {}    y = {:8f}".format(datetime.fromtimestamp(t, tz), y)
88 
89     return lines
90 
91 
92 def _maybe_resample(series, ax, freq, plotf, kwargs):
93     ax_freq = _get_ax_freq(ax)
94     if ax_freq is not None and freq != ax_freq:
95         if frequencies.is_superperiod(freq, ax_freq):  # upsample input
96             series = series.copy()
97             series.index = series.index.asfreq(ax_freq, how='s')
98             freq = ax_freq
99         elif _is_sup(freq, ax_freq):  # one is weekly
100             how = kwargs.pop('how', 'last')
101             series = series.resample('D', how=how).dropna()
102             series = series.resample(ax_freq, how=how).dropna()
103             freq = ax_freq
104         elif frequencies.is_subperiod(freq, ax_freq) or _is_sub(freq, ax_freq):
105             _upsample_others(ax, freq, plotf, kwargs)
106             ax_freq = freq
107         else:  # pragma: no cover
108             raise ValueError('Incompatible frequency conversion')
109     return freq, ax_freq, series
110 
111 
112 def _get_ax_freq(ax):
113     ax_freq = getattr(ax, 'freq', None)
114     if ax_freq is None:
115         if hasattr(ax, 'left_ax'):
116             ax_freq = getattr(ax.left_ax, 'freq', None)
117         if hasattr(ax, 'right_ax'):
118             ax_freq = getattr(ax.right_ax, 'freq', None)
119     return ax_freq
120 
121 
122 def _is_sub(f1, f2):
123     return ((f1.startswith('W') and frequencies.is_subperiod('D', f2)) or
124             (f2.startswith('W') and frequencies.is_subperiod(f1, 'D')))
125 
126 
127 def _is_sup(f1, f2):
128     return ((f1.startswith('W') and frequencies.is_superperiod('D', f2)) or
129             (f2.startswith('W') and frequencies.is_superperiod(f1, 'D')))
130 
131 
132 def _upsample_others(ax, freq, plotf, kwargs):
133     legend = ax.get_legend()
134     lines, labels = _replot_ax(ax, freq, plotf, kwargs)
135 
136     other_ax = None
137     if hasattr(ax, 'left_ax'):
138         other_ax = ax.left_ax
139     if hasattr(ax, 'right_ax'):
140         other_ax = ax.right_ax
141 
142     if other_ax is not None:
143         rlines, rlabels = _replot_ax(other_ax, freq, plotf, kwargs)
144         lines.extend(rlines)
145         labels.extend(rlabels)
146 
147     if (legend is not None and kwargs.get('legend', True) and
148             len(lines) > 0):
149         title = legend.get_title().get_text()
150         if title == 'None':
151             title = None
152         ax.legend(lines, labels, loc='best', title=title)
153 
154 
155 def _replot_ax(ax, freq, plotf, kwargs):
156     data = getattr(ax, '_plot_data', None)
157     ax._plot_data = []
158     ax.clear()
159     _decorate_axes(ax, freq, kwargs)
160 
161     lines = []
162     labels = []
163     if data is not None:
164         for series, kwds in data:
165             series = series.copy()
166             idx = series.index.asfreq(freq, how='S')
167             series.index = idx
168             ax._plot_data.append(series)
169             args = _maybe_mask(series)
170             lines.append(plotf(ax, *args, **kwds)[0])
171             labels.append(com.pprint_thing(series.name))
172 
173     return lines, labels
174 
175 
176 def _decorate_axes(ax, freq, kwargs):
177     ax.freq = freq
178     xaxis = ax.get_xaxis()
179     xaxis.freq = freq
180     if not hasattr(ax, 'legendlabels'):
181         ax.legendlabels = [kwargs.get('label', None)]
182     else:
183         ax.legendlabels.append(kwargs.get('label', None))
184     ax.view_interval = None
185     ax.date_axis_info = None
186 
187 
188 def _maybe_mask(series):
189     mask = isnull(series)
190     if mask.any():
191         masked_array = np.ma.array(series.values)
192         masked_array = np.ma.masked_where(mask, masked_array)
193         args = [series.index, masked_array]
194     else:
195         args = [series.index, series.values]
196     return args
197 
198 
199 def _get_freq(ax, series):
200     # get frequency from data
201     freq = getattr(series.index, 'freq', None)
202     if freq is None:
203         freq = getattr(series.index, 'inferred_freq', None)
204 
205     ax_freq = getattr(ax, 'freq', None)
206 
207     # use axes freq if no data freq
208     if freq is None:
209         freq = ax_freq
210 
211     # get the period frequency
212     if isinstance(freq, DateOffset):
213         freq = freq.rule_code
214     else:
215         freq = frequencies.get_base_alias(freq)
216 
217     freq = frequencies.get_period_alias(freq)
218 
219     return freq
220 
221 
222 def _get_xlim(lines):
223     left, right = np.inf, -np.inf
224     for l in lines:
225         x = l.get_xdata()
226         left = min(x[0].ordinal, left)
227         right = max(x[-1].ordinal, right)
228     return left, right
229 
230 # Patch methods for subplot. Only format_dateaxis is currently used.
231 # Do we need the rest for convenience?
232 
233 
234 def format_dateaxis(subplot, freq):
235     """
236     Pretty-formats the date axis (x-axis).
237 
238     Major and minor ticks are automatically set for the frequency of the
239     current underlying series.  As the dynamic mode is activated by
240     default, changing the limits of the x axis will intelligently change
241     the positions of the ticks.
242     """
243     majlocator = TimeSeries_DateLocator(freq, dynamic_mode=True,
244                                         minor_locator=False,
245                                         plot_obj=subplot)
246     minlocator = TimeSeries_DateLocator(freq, dynamic_mode=True,
247                                         minor_locator=True,
248                                         plot_obj=subplot)
249     subplot.xaxis.set_major_locator(majlocator)
250     subplot.xaxis.set_minor_locator(minlocator)
251 
252     majformatter = TimeSeries_DateFormatter(freq, dynamic_mode=True,
253                                             minor_locator=False,
254                                             plot_obj=subplot)
255     minformatter = TimeSeries_DateFormatter(freq, dynamic_mode=True,
256                                             minor_locator=True,
257                                             plot_obj=subplot)
258     subplot.xaxis.set_major_formatter(majformatter)
259     subplot.xaxis.set_minor_formatter(minformatter)
260     pylab.draw_if_interactive()
261
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pandas/tseries/plotting.py b/pandas/tseries/plotting.py
--- a/pandas/tseries/plotting.py
+++ b/pandas/tseries/plotting.py
@@ -83,8 +83,7 @@
     ax.set_xlim(left, right)
 
     # x and y coord info
-    tz = series.index.to_datetime().tz
-    ax.format_coord = lambda t, y : "t = {}    y = {:8f}".format(datetime.fromtimestamp(t, tz), y)
+    ax.format_coord = lambda t, y: "t = {}  y = {:8f}".format(Period(ordinal=int(t), freq=ax.freq), y)
 
     return lines

{"golden_diff": "diff --git a/pandas/tseries/plotting.py b/pandas/tseries/plotting.py\n--- a/pandas/tseries/plotting.py\n+++ b/pandas/tseries/plotting.py\n@@ -83,8 +83,7 @@\n     ax.set_xlim(left, right)\n \n     # x and y coord info\n-    tz = series.index.to_datetime().tz\n-    ax.format_coord = lambda t, y : \"t = {}    y = {:8f}\".format(datetime.fromtimestamp(t, tz), y)\n+    ax.format_coord = lambda t, y: \"t = {}  y = {:8f}\".format(Period(ordinal=int(t), freq=ax.freq), y)\n \n     return lines\n", "issue": "Matplotlib cursor position wrong after using asfreq method to change freq of DateTimeIndex from None to something\nAfter using the `asfreq` method to change the frequency of a time-series DataFrame from `None` to something e.g. `15Min` the cursor position in matplotlib graphs of that DataFrame is no longer correct (usually shows a datetime just after the unix epoch).  The following demonstrates this (NB dt in df1 is not a constant):\n\n```\ndf1 = pandas.read_csv('tseries1.csv', names=['tstamp', 'Q'], parse_dates=True, \n    index_col='tstamp').clip_lower(0).fillna(0)\ndf1['T'] = pandas.read_csv('tseries2.csv', names=['tstamp', 'T'], parse_dates=True, \n    index_col='tstamp', squeeze=True).clip_lower(0).fillna(0)\n\ndf2 = df1.asfreq(freq='15Min', method='ffill')\n# NB df1.index.freq is None\n# NB df2.index.freq is <15 * Minutes>\ndf1.plot()\ndf2.plot()\nplt.show()\n```\n\nI find the Matplotlib cursor position to be invaluable when looking for features in very long time-series.\n\nVersions:\n- pandas master (commit ID 764b444)\n- numpy 1.8\n- matplotlib 1.3.0\n\nMatplotlib cursor position wrong after using asfreq method to change freq of DateTimeIndex from None to something\nAfter using the `asfreq` method to change the frequency of a time-series DataFrame from `None` to something e.g. `15Min` the cursor position in matplotlib graphs of that DataFrame is no longer correct (usually shows a datetime just after the unix epoch).  The following demonstrates this (NB dt in df1 is not a constant):\n\n```\ndf1 = pandas.read_csv('tseries1.csv', names=['tstamp', 'Q'], parse_dates=True, \n    index_col='tstamp').clip_lower(0).fillna(0)\ndf1['T'] = pandas.read_csv('tseries2.csv', names=['tstamp', 'T'], parse_dates=True, \n    index_col='tstamp', squeeze=True).clip_lower(0).fillna(0)\n\ndf2 = df1.asfreq(freq='15Min', method='ffill')\n# NB df1.index.freq is None\n# NB df2.index.freq is <15 * Minutes>\ndf1.plot()\ndf2.plot()\nplt.show()\n```\n\nI find the Matplotlib cursor position to be invaluable when looking for features in very long time-series.\n\nVersions:\n- pandas master (commit ID 764b444)\n- numpy 1.8\n- matplotlib 1.3.0\n\n", "before_files": [{"content": "\"\"\"\nPeriod formatters and locators adapted from scikits.timeseries by\nPierre GF Gerard-Marchant & Matt Knox\n\"\"\"\n\n#!!! TODO: Use the fact that axis can have units to simplify the process\nimport datetime as pydt\nfrom datetime import datetime\n\nfrom matplotlib import pylab\nimport matplotlib.units as units\n\nimport numpy as np\n\nfrom pandas import isnull\nfrom pandas.tseries.period import Period\nfrom pandas.tseries.offsets import DateOffset\nimport pandas.tseries.frequencies as frequencies\nfrom pandas.tseries.index import DatetimeIndex\nimport pandas.core.common as com\n\nfrom pandas.tseries.converter import (PeriodConverter, TimeSeries_DateLocator,\n                                      TimeSeries_DateFormatter)\n\n#----------------------------------------------------------------------\n# Plotting functions and monkey patches\n\n\ndef tsplot(series, plotf, **kwargs):\n    \"\"\"\n    Plots a Series on the given Matplotlib axes or the current axes\n\n    Parameters\n    ----------\n    axes : Axes\n    series : Series\n\n    Notes\n    _____\n    Supports same kwargs as Axes.plot\n\n    \"\"\"\n    # Used inferred freq is possible, need a test case for inferred\n    if 'ax' in kwargs:\n        ax = kwargs.pop('ax')\n    else:\n        import matplotlib.pyplot as plt\n        ax = plt.gca()\n\n    freq = _get_freq(ax, series)\n    # resample against axes freq if necessary\n    if freq is None:  # pragma: no cover\n        raise ValueError('Cannot use dynamic axis without frequency info')\n    else:\n        # Convert DatetimeIndex to PeriodIndex\n        if isinstance(series.index, DatetimeIndex):\n            series = series.to_period(freq=freq)\n        freq, ax_freq, series = _maybe_resample(series, ax, freq, plotf,\n                                                kwargs)\n\n    # Set ax with freq info\n    _decorate_axes(ax, freq, kwargs)\n\n    # mask missing values\n    args = _maybe_mask(series)\n\n    # how to make sure ax.clear() flows through?\n    if not hasattr(ax, '_plot_data'):\n        ax._plot_data = []\n    ax._plot_data.append((series, kwargs))\n\n    # styles\n    style = kwargs.pop('style', None)\n    if style is not None:\n        args.append(style)\n\n    lines = plotf(ax, *args, **kwargs)\n    label = kwargs.get('label', None)\n\n    # set date formatter, locators and rescale limits\n    format_dateaxis(ax, ax.freq)\n    left, right = _get_xlim(ax.get_lines())\n    ax.set_xlim(left, right)\n\n    # x and y coord info\n    tz = series.index.to_datetime().tz\n    ax.format_coord = lambda t, y : \"t = {}    y = {:8f}\".format(datetime.fromtimestamp(t, tz), y)\n\n    return lines\n\n\ndef _maybe_resample(series, ax, freq, plotf, kwargs):\n    ax_freq = _get_ax_freq(ax)\n    if ax_freq is not None and freq != ax_freq:\n        if frequencies.is_superperiod(freq, ax_freq):  # upsample input\n            series = series.copy()\n            series.index = series.index.asfreq(ax_freq, how='s')\n            freq = ax_freq\n        elif _is_sup(freq, ax_freq):  # one is weekly\n            how = kwargs.pop('how', 'last')\n            series = series.resample('D', how=how).dropna()\n            series = series.resample(ax_freq, how=how).dropna()\n            freq = ax_freq\n        elif frequencies.is_subperiod(freq, ax_freq) or _is_sub(freq, ax_freq):\n            _upsample_others(ax, freq, plotf, kwargs)\n            ax_freq = freq\n        else:  # pragma: no cover\n            raise ValueError('Incompatible frequency conversion')\n    return freq, ax_freq, series\n\n\ndef _get_ax_freq(ax):\n    ax_freq = getattr(ax, 'freq', None)\n    if ax_freq is None:\n        if hasattr(ax, 'left_ax'):\n            ax_freq = getattr(ax.left_ax, 'freq', None)\n        if hasattr(ax, 'right_ax'):\n            ax_freq = getattr(ax.right_ax, 'freq', None)\n    return ax_freq\n\n\ndef _is_sub(f1, f2):\n    return ((f1.startswith('W') and frequencies.is_subperiod('D', f2)) or\n            (f2.startswith('W') and frequencies.is_subperiod(f1, 'D')))\n\n\ndef _is_sup(f1, f2):\n    return ((f1.startswith('W') and frequencies.is_superperiod('D', f2)) or\n            (f2.startswith('W') and frequencies.is_superperiod(f1, 'D')))\n\n\ndef _upsample_others(ax, freq, plotf, kwargs):\n    legend = ax.get_legend()\n    lines, labels = _replot_ax(ax, freq, plotf, kwargs)\n\n    other_ax = None\n    if hasattr(ax, 'left_ax'):\n        other_ax = ax.left_ax\n    if hasattr(ax, 'right_ax'):\n        other_ax = ax.right_ax\n\n    if other_ax is not None:\n        rlines, rlabels = _replot_ax(other_ax, freq, plotf, kwargs)\n        lines.extend(rlines)\n        labels.extend(rlabels)\n\n    if (legend is not None and kwargs.get('legend', True) and\n            len(lines) > 0):\n        title = legend.get_title().get_text()\n        if title == 'None':\n            title = None\n        ax.legend(lines, labels, loc='best', title=title)\n\n\ndef _replot_ax(ax, freq, plotf, kwargs):\n    data = getattr(ax, '_plot_data', None)\n    ax._plot_data = []\n    ax.clear()\n    _decorate_axes(ax, freq, kwargs)\n\n    lines = []\n    labels = []\n    if data is not None:\n        for series, kwds in data:\n            series = series.copy()\n            idx = series.index.asfreq(freq, how='S')\n            series.index = idx\n            ax._plot_data.append(series)\n            args = _maybe_mask(series)\n            lines.append(plotf(ax, *args, **kwds)[0])\n            labels.append(com.pprint_thing(series.name))\n\n    return lines, labels\n\n\ndef _decorate_axes(ax, freq, kwargs):\n    ax.freq = freq\n    xaxis = ax.get_xaxis()\n    xaxis.freq = freq\n    if not hasattr(ax, 'legendlabels'):\n        ax.legendlabels = [kwargs.get('label', None)]\n    else:\n        ax.legendlabels.append(kwargs.get('label', None))\n    ax.view_interval = None\n    ax.date_axis_info = None\n\n\ndef _maybe_mask(series):\n    mask = isnull(series)\n    if mask.any():\n        masked_array = np.ma.array(series.values)\n        masked_array = np.ma.masked_where(mask, masked_array)\n        args = [series.index, masked_array]\n    else:\n        args = [series.index, series.values]\n    return args\n\n\ndef _get_freq(ax, series):\n    # get frequency from data\n    freq = getattr(series.index, 'freq', None)\n    if freq is None:\n        freq = getattr(series.index, 'inferred_freq', None)\n\n    ax_freq = getattr(ax, 'freq', None)\n\n    # use axes freq if no data freq\n    if freq is None:\n        freq = ax_freq\n\n    # get the period frequency\n    if isinstance(freq, DateOffset):\n        freq = freq.rule_code\n    else:\n        freq = frequencies.get_base_alias(freq)\n\n    freq = frequencies.get_period_alias(freq)\n\n    return freq\n\n\ndef _get_xlim(lines):\n    left, right = np.inf, -np.inf\n    for l in lines:\n        x = l.get_xdata()\n        left = min(x[0].ordinal, left)\n        right = max(x[-1].ordinal, right)\n    return left, right\n\n# Patch methods for subplot. Only format_dateaxis is currently used.\n# Do we need the rest for convenience?\n\n\ndef format_dateaxis(subplot, freq):\n    \"\"\"\n    Pretty-formats the date axis (x-axis).\n\n    Major and minor ticks are automatically set for the frequency of the\n    current underlying series.  As the dynamic mode is activated by\n    default, changing the limits of the x axis will intelligently change\n    the positions of the ticks.\n    \"\"\"\n    majlocator = TimeSeries_DateLocator(freq, dynamic_mode=True,\n                                        minor_locator=False,\n                                        plot_obj=subplot)\n    minlocator = TimeSeries_DateLocator(freq, dynamic_mode=True,\n                                        minor_locator=True,\n                                        plot_obj=subplot)\n    subplot.xaxis.set_major_locator(majlocator)\n    subplot.xaxis.set_minor_locator(minlocator)\n\n    majformatter = TimeSeries_DateFormatter(freq, dynamic_mode=True,\n                                            minor_locator=False,\n                                            plot_obj=subplot)\n    minformatter = TimeSeries_DateFormatter(freq, dynamic_mode=True,\n                                            minor_locator=True,\n                                            plot_obj=subplot)\n    subplot.xaxis.set_major_formatter(majformatter)\n    subplot.xaxis.set_minor_formatter(minformatter)\n    pylab.draw_if_interactive()\n", "path": "pandas/tseries/plotting.py"}], "after_files": [{"content": "\"\"\"\nPeriod formatters and locators adapted from scikits.timeseries by\nPierre GF Gerard-Marchant & Matt Knox\n\"\"\"\n\n#!!! TODO: Use the fact that axis can have units to simplify the process\nimport datetime as pydt\nfrom datetime import datetime\n\nfrom matplotlib import pylab\nimport matplotlib.units as units\n\nimport numpy as np\n\nfrom pandas import isnull\nfrom pandas.tseries.period import Period\nfrom pandas.tseries.offsets import DateOffset\nimport pandas.tseries.frequencies as frequencies\nfrom pandas.tseries.index import DatetimeIndex\nimport pandas.core.common as com\n\nfrom pandas.tseries.converter import (PeriodConverter, TimeSeries_DateLocator,\n                                      TimeSeries_DateFormatter)\n\n#----------------------------------------------------------------------\n# Plotting functions and monkey patches\n\n\ndef tsplot(series, plotf, **kwargs):\n    \"\"\"\n    Plots a Series on the given Matplotlib axes or the current axes\n\n    Parameters\n    ----------\n    axes : Axes\n    series : Series\n\n    Notes\n    _____\n    Supports same kwargs as Axes.plot\n\n    \"\"\"\n    # Used inferred freq is possible, need a test case for inferred\n    if 'ax' in kwargs:\n        ax = kwargs.pop('ax')\n    else:\n        import matplotlib.pyplot as plt\n        ax = plt.gca()\n\n    freq = _get_freq(ax, series)\n    # resample against axes freq if necessary\n    if freq is None:  # pragma: no cover\n        raise ValueError('Cannot use dynamic axis without frequency info')\n    else:\n        # Convert DatetimeIndex to PeriodIndex\n        if isinstance(series.index, DatetimeIndex):\n            series = series.to_period(freq=freq)\n        freq, ax_freq, series = _maybe_resample(series, ax, freq, plotf,\n                                                kwargs)\n\n    # Set ax with freq info\n    _decorate_axes(ax, freq, kwargs)\n\n    # mask missing values\n    args = _maybe_mask(series)\n\n    # how to make sure ax.clear() flows through?\n    if not hasattr(ax, '_plot_data'):\n        ax._plot_data = []\n    ax._plot_data.append((series, kwargs))\n\n    # styles\n    style = kwargs.pop('style', None)\n    if style is not None:\n        args.append(style)\n\n    lines = plotf(ax, *args, **kwargs)\n    label = kwargs.get('label', None)\n\n    # set date formatter, locators and rescale limits\n    format_dateaxis(ax, ax.freq)\n    left, right = _get_xlim(ax.get_lines())\n    ax.set_xlim(left, right)\n\n    # x and y coord info\n    ax.format_coord = lambda t, y: \"t = {}  y = {:8f}\".format(Period(ordinal=int(t), freq=ax.freq), y)\n\n    return lines\n\n\ndef _maybe_resample(series, ax, freq, plotf, kwargs):\n    ax_freq = _get_ax_freq(ax)\n    if ax_freq is not None and freq != ax_freq:\n        if frequencies.is_superperiod(freq, ax_freq):  # upsample input\n            series = series.copy()\n            series.index = series.index.asfreq(ax_freq, how='s')\n            freq = ax_freq\n        elif _is_sup(freq, ax_freq):  # one is weekly\n            how = kwargs.pop('how', 'last')\n            series = series.resample('D', how=how).dropna()\n            series = series.resample(ax_freq, how=how).dropna()\n            freq = ax_freq\n        elif frequencies.is_subperiod(freq, ax_freq) or _is_sub(freq, ax_freq):\n            _upsample_others(ax, freq, plotf, kwargs)\n            ax_freq = freq\n        else:  # pragma: no cover\n            raise ValueError('Incompatible frequency conversion')\n    return freq, ax_freq, series\n\n\ndef _get_ax_freq(ax):\n    ax_freq = getattr(ax, 'freq', None)\n    if ax_freq is None:\n        if hasattr(ax, 'left_ax'):\n            ax_freq = getattr(ax.left_ax, 'freq', None)\n        if hasattr(ax, 'right_ax'):\n            ax_freq = getattr(ax.right_ax, 'freq', None)\n    return ax_freq\n\n\ndef _is_sub(f1, f2):\n    return ((f1.startswith('W') and frequencies.is_subperiod('D', f2)) or\n            (f2.startswith('W') and frequencies.is_subperiod(f1, 'D')))\n\n\ndef _is_sup(f1, f2):\n    return ((f1.startswith('W') and frequencies.is_superperiod('D', f2)) or\n            (f2.startswith('W') and frequencies.is_superperiod(f1, 'D')))\n\n\ndef _upsample_others(ax, freq, plotf, kwargs):\n    legend = ax.get_legend()\n    lines, labels = _replot_ax(ax, freq, plotf, kwargs)\n\n    other_ax = None\n    if hasattr(ax, 'left_ax'):\n        other_ax = ax.left_ax\n    if hasattr(ax, 'right_ax'):\n        other_ax = ax.right_ax\n\n    if other_ax is not None:\n        rlines, rlabels = _replot_ax(other_ax, freq, plotf, kwargs)\n        lines.extend(rlines)\n        labels.extend(rlabels)\n\n    if (legend is not None and kwargs.get('legend', True) and\n            len(lines) > 0):\n        title = legend.get_title().get_text()\n        if title == 'None':\n            title = None\n        ax.legend(lines, labels, loc='best', title=title)\n\n\ndef _replot_ax(ax, freq, plotf, kwargs):\n    data = getattr(ax, '_plot_data', None)\n    ax._plot_data = []\n    ax.clear()\n    _decorate_axes(ax, freq, kwargs)\n\n    lines = []\n    labels = []\n    if data is not None:\n        for series, kwds in data:\n            series = series.copy()\n            idx = series.index.asfreq(freq, how='S')\n            series.index = idx\n            ax._plot_data.append(series)\n            args = _maybe_mask(series)\n            lines.append(plotf(ax, *args, **kwds)[0])\n            labels.append(com.pprint_thing(series.name))\n\n    return lines, labels\n\n\ndef _decorate_axes(ax, freq, kwargs):\n    ax.freq = freq\n    xaxis = ax.get_xaxis()\n    xaxis.freq = freq\n    if not hasattr(ax, 'legendlabels'):\n        ax.legendlabels = [kwargs.get('label', None)]\n    else:\n        ax.legendlabels.append(kwargs.get('label', None))\n    ax.view_interval = None\n    ax.date_axis_info = None\n\n\ndef _maybe_mask(series):\n    mask = isnull(series)\n    if mask.any():\n        masked_array = np.ma.array(series.values)\n        masked_array = np.ma.masked_where(mask, masked_array)\n        args = [series.index, masked_array]\n    else:\n        args = [series.index, series.values]\n    return args\n\n\ndef _get_freq(ax, series):\n    # get frequency from data\n    freq = getattr(series.index, 'freq', None)\n    if freq is None:\n        freq = getattr(series.index, 'inferred_freq', None)\n\n    ax_freq = getattr(ax, 'freq', None)\n\n    # use axes freq if no data freq\n    if freq is None:\n        freq = ax_freq\n\n    # get the period frequency\n    if isinstance(freq, DateOffset):\n        freq = freq.rule_code\n    else:\n        freq = frequencies.get_base_alias(freq)\n\n    freq = frequencies.get_period_alias(freq)\n\n    return freq\n\n\ndef _get_xlim(lines):\n    left, right = np.inf, -np.inf\n    for l in lines:\n        x = l.get_xdata()\n        left = min(x[0].ordinal, left)\n        right = max(x[-1].ordinal, right)\n    return left, right\n\n# Patch methods for subplot. Only format_dateaxis is currently used.\n# Do we need the rest for convenience?\n\n\ndef format_dateaxis(subplot, freq):\n    \"\"\"\n    Pretty-formats the date axis (x-axis).\n\n    Major and minor ticks are automatically set for the frequency of the\n    current underlying series.  As the dynamic mode is activated by\n    default, changing the limits of the x axis will intelligently change\n    the positions of the ticks.\n    \"\"\"\n    majlocator = TimeSeries_DateLocator(freq, dynamic_mode=True,\n                                        minor_locator=False,\n                                        plot_obj=subplot)\n    minlocator = TimeSeries_DateLocator(freq, dynamic_mode=True,\n                                        minor_locator=True,\n                                        plot_obj=subplot)\n    subplot.xaxis.set_major_locator(majlocator)\n    subplot.xaxis.set_minor_locator(minlocator)\n\n    majformatter = TimeSeries_DateFormatter(freq, dynamic_mode=True,\n                                            minor_locator=False,\n                                            plot_obj=subplot)\n    minformatter = TimeSeries_DateFormatter(freq, dynamic_mode=True,\n                                            minor_locator=True,\n                                            plot_obj=subplot)\n    subplot.xaxis.set_major_formatter(majformatter)\n    subplot.xaxis.set_minor_formatter(minformatter)\n    pylab.draw_if_interactive()\n", "path": "pandas/tseries/plotting.py"}]}