From b1141fd7bc11f69246141a2d40d7fc49a03f8b69 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Fri, 22 Mar 2019 19:34:19 +0100 Subject: [PATCH 1/2] Deprecate plotfile. Various replacements are showcased in plotfile_demo_sgskip. --- doc/api/next_api_changes/2019-03-23-AL.rst | 7 ++ examples/misc/plotfile_demo.py | 45 ----------- examples/misc/plotfile_demo_sgskip.py | 89 ++++++++++++++++++++++ examples/tests/backend_driver_sgskip.py | 1 - lib/matplotlib/pyplot.py | 1 + 5 files changed, 97 insertions(+), 46 deletions(-) create mode 100644 doc/api/next_api_changes/2019-03-23-AL.rst delete mode 100644 examples/misc/plotfile_demo.py create mode 100644 examples/misc/plotfile_demo_sgskip.py diff --git a/doc/api/next_api_changes/2019-03-23-AL.rst b/doc/api/next_api_changes/2019-03-23-AL.rst new file mode 100644 index 000000000000..4d5b7e6d2788 --- /dev/null +++ b/doc/api/next_api_changes/2019-03-23-AL.rst @@ -0,0 +1,7 @@ +Deprecations +```````````` + +`.pyplot.plotfile` is deprecated in favor of separately loading and plotting +the data. See :doc:`/gallery/misc/plotfile_demo_sgskip` for various ways to +use pandas or numpy to load data, and pandas or matplotlib to plot the +resulting data. diff --git a/examples/misc/plotfile_demo.py b/examples/misc/plotfile_demo.py deleted file mode 100644 index d55323b1f7c7..000000000000 --- a/examples/misc/plotfile_demo.py +++ /dev/null @@ -1,45 +0,0 @@ -""" -============= -Plotfile Demo -============= - -Example use of ``plotfile`` to plot data directly from a file. -""" - -import matplotlib.pyplot as plt -import matplotlib.cbook as cbook - -fname = cbook.get_sample_data('msft.csv', asfileobj=False) -fname2 = cbook.get_sample_data('data_x_x2_x3.csv', asfileobj=False) - -# test 1; use ints -plt.plotfile(fname, (0, 5, 6)) - -# test 2; use names -plt.plotfile(fname, ('date', 'volume', 'adj_close')) - -# test 3; use semilogy for volume -plt.plotfile(fname, ('date', 'volume', 'adj_close'), - plotfuncs={'volume': 'semilogy'}) - -# test 4; use semilogy for volume -plt.plotfile(fname, (0, 5, 6), plotfuncs={5: 'semilogy'}) - -# test 5; single subplot -plt.plotfile(fname, ('date', 'open', 'high', 'low', 'close'), subplots=False) - -# test 6; labeling, if no names in csv-file -plt.plotfile(fname2, cols=(0, 1, 2), delimiter=' ', - names=['$x$', '$f(x)=x^2$', '$f(x)=x^3$']) - -# test 7; more than one file per figure--illustrated here with a single file -plt.plotfile(fname2, cols=(0, 1), delimiter=' ') -plt.plotfile(fname2, cols=(0, 2), newfig=False, - delimiter=' ') # use current figure -plt.xlabel(r'$x$') -plt.ylabel(r'$f(x) = x^2, x^3$') - -# test 8; use bar for volume -plt.plotfile(fname, (0, 5, 6), plotfuncs={5: 'bar'}) - -plt.show() diff --git a/examples/misc/plotfile_demo_sgskip.py b/examples/misc/plotfile_demo_sgskip.py new file mode 100644 index 000000000000..4264baba8881 --- /dev/null +++ b/examples/misc/plotfile_demo_sgskip.py @@ -0,0 +1,89 @@ +""" +============= +plotfile demo +============= + +Replacing the deprecated `plotfile` by pandas or other matplotlib plotting +methods. +""" + +import matplotlib.pyplot as plt +import matplotlib.cbook as cbook + +import numpy as np +import pandas as pd +pd.plotting.register_matplotlib_converters() + +# Time series. +fname = cbook.get_sample_data('msft.csv', asfileobj=False) +with cbook.get_sample_data('msft.csv') as file: + msft = pd.read_csv(file, parse_dates=['Date']) + +# Use indices. +plt.plotfile(fname, (0, 5, 6)) + +msft.plot(0, [5, 6], subplots=True) + +# Use names. +plt.plotfile(fname, ('date', 'volume', 'adj_close')) + +msft.plot("Date", ["Volume", "Adj. Close*"], subplots=True) + +# Use semilogy for volume. +plt.plotfile(fname, ('date', 'volume', 'adj_close'), + plotfuncs={'volume': 'semilogy'}) + +fig, axs = plt.subplots(2, sharex=True) +msft.plot("Date", "Volume", ax=axs[0], logy=True) +msft.plot("Date", "Adj. Close*", ax=axs[1]) + +# Use semilogy for volume (by index). +plt.plotfile(fname, (0, 5, 6), plotfuncs={5: 'semilogy'}) + +fig, axs = plt.subplots(2, sharex=True) +msft.plot(0, 5, ax=axs[0], logy=True) +msft.plot(0, 6, ax=axs[1]) + +# Single subplot +plt.plotfile(fname, ('date', 'open', 'high', 'low', 'close'), subplots=False) + +msft.plot("Date", ["Open", "High", "Low", "Close"]) + +# Use bar for volume +plt.plotfile(fname, (0, 5, 6), plotfuncs={5: "bar"}) + +fig, axs = plt.subplots(2, sharex=True) +axs[0].bar(msft.iloc[:, 0], msft.iloc[:, 5]) +axs[1].plot(msft.iloc[:, 0], msft.iloc[:, 6]) +fig.autofmt_xdate() + +############################################################################### + +# Unlabeled data. +fname2 = cbook.get_sample_data('data_x_x2_x3.csv', asfileobj=False) +with cbook.get_sample_data('data_x_x2_x3.csv') as file: + array = np.loadtxt(file) + +# Labeling, if no names in csv-file. +plt.plotfile(fname2, cols=(0, 1, 2), delimiter=' ', + names=['$x$', '$f(x)=x^2$', '$f(x)=x^3$']) + +fig, axs = plt.subplots(2, sharex=True) +axs[0].plot(array[:, 0], array[:, 1]) +axs[0].set(ylabel='$f(x)=x^2$') +axs[1].plot(array[:, 0], array[:, 2]) +axs[1].set(xlabel='$x$', ylabel='$f(x)=x^3$') + +# More than one file per figure--illustrated here with a single file. +plt.plotfile(fname2, cols=(0, 1), delimiter=' ') +plt.plotfile(fname2, cols=(0, 2), newfig=False, + delimiter=' ') # use current figure +plt.xlabel(r'$x$') +plt.ylabel(r'$f(x) = x^2, x^3$') + +fig, ax = plt.subplots() +ax.plot(array[:, 0], array[:, 1]) +ax.plot(array[:, 0], array[:, 2]) +ax.set(xlabel='$x$', ylabel='$f(x)=x^3$') + +plt.show() diff --git a/examples/tests/backend_driver_sgskip.py b/examples/tests/backend_driver_sgskip.py index 8878c6273bce..761287e5e292 100644 --- a/examples/tests/backend_driver_sgskip.py +++ b/examples/tests/backend_driver_sgskip.py @@ -212,7 +212,6 @@ 'pcolor_log.py', 'pcolor_small.py', 'pie_demo2.py', - 'plotfile_demo.py', 'polar_demo.py', 'polar_legend.py', 'psd_demo.py', diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 84cf4fc723cd..6d12da9b1c40 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -2176,6 +2176,7 @@ def polar(*args, **kwargs): return ret +@cbook.deprecated("3.1") def plotfile(fname, cols=(0,), plotfuncs=None, comments='#', skiprows=0, checkrows=5, delimiter=',', names=None, subplots=True, newfig=True, **kwargs): From 7ac93a01bb1cdf468b13a22b83fd638af19f0ad7 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Tue, 9 Apr 2019 21:09:05 +0200 Subject: [PATCH 2/2] More explanation on plotting data from files --- examples/misc/plotfile_demo_sgskip.py | 113 ++++++++++++++++++++++---- 1 file changed, 97 insertions(+), 16 deletions(-) diff --git a/examples/misc/plotfile_demo_sgskip.py b/examples/misc/plotfile_demo_sgskip.py index 4264baba8881..29bc0c1fac31 100644 --- a/examples/misc/plotfile_demo_sgskip.py +++ b/examples/misc/plotfile_demo_sgskip.py @@ -1,10 +1,23 @@ """ -============= -plotfile demo -============= +========================= +Plotting data from a file +========================= -Replacing the deprecated `plotfile` by pandas or other matplotlib plotting -methods. +Plotting data from a file is actually a two-step process. + +1. Interpreting the file and loading the data. +2. Creating the actual plot. + +`.pyplot.plotfile` tried to do both at once. But each of the steps has so many +possible variations and parameters that it does not make sense to squeeze both +into a single function. Therefore, `.pyplot.plotfile` has been deprecated. + +The recommended way of plotting data from a file is therefore to use dedicated +functions such as `numpy.loadtxt` or `pandas.read_csv` to read the data. These +are more powerful and faster. Then plot the obtained data using matplotlib. + +Note that `pandas.DataFrame.plot` is a convenient wrapper around Matplotlib +to create simple plots. """ import matplotlib.pyplot as plt @@ -12,75 +25,143 @@ import numpy as np import pandas as pd -pd.plotting.register_matplotlib_converters() -# Time series. +############################################################################### +# Using pandas +# ============ +# +# Subsequent are a few examples of how to replace `~.pyplot.plotfile` with +# `pandas`. All examples need the the `pandas.read_csv` call first. Note that +# you can use the filename directly as a parameter:: +# +# msft = pd.read_csv('msft.csv') +# +# The following slightly more involved `pandas.read_csv` call is only to make +# automatic rendering of the example work: + fname = cbook.get_sample_data('msft.csv', asfileobj=False) +with cbook.get_sample_data('msft.csv') as file: + msft = pd.read_csv(file) + +############################################################################### +# When working with dates, additionally call +# `pandas.plotting.register_matplotlib_converters` and use the ``parse_dates`` +# argument of `pandas.read_csv`:: + +pd.plotting.register_matplotlib_converters() + with cbook.get_sample_data('msft.csv') as file: msft = pd.read_csv(file, parse_dates=['Date']) -# Use indices. + +############################################################################### +# Use indices +# ----------- + +# Deprecated: plt.plotfile(fname, (0, 5, 6)) +# Use instead: msft.plot(0, [5, 6], subplots=True) -# Use names. +############################################################################### +# Use names +# --------- + +# Deprecated: plt.plotfile(fname, ('date', 'volume', 'adj_close')) +# Use instead: msft.plot("Date", ["Volume", "Adj. Close*"], subplots=True) -# Use semilogy for volume. +############################################################################### +# Use semilogy for volume +# ----------------------- + +# Deprecated: plt.plotfile(fname, ('date', 'volume', 'adj_close'), plotfuncs={'volume': 'semilogy'}) +# Use instead: fig, axs = plt.subplots(2, sharex=True) msft.plot("Date", "Volume", ax=axs[0], logy=True) msft.plot("Date", "Adj. Close*", ax=axs[1]) -# Use semilogy for volume (by index). + +############################################################################### +# Use semilogy for volume (by index) +# ---------------------------------- + +# Deprecated: plt.plotfile(fname, (0, 5, 6), plotfuncs={5: 'semilogy'}) +# Use instead: fig, axs = plt.subplots(2, sharex=True) msft.plot(0, 5, ax=axs[0], logy=True) msft.plot(0, 6, ax=axs[1]) +############################################################################### # Single subplot +# -------------- + +# Deprecated: plt.plotfile(fname, ('date', 'open', 'high', 'low', 'close'), subplots=False) +# Use instead: msft.plot("Date", ["Open", "High", "Low", "Close"]) +############################################################################### # Use bar for volume +# ------------------ + +# Deprecated: plt.plotfile(fname, (0, 5, 6), plotfuncs={5: "bar"}) +# Use instead: fig, axs = plt.subplots(2, sharex=True) axs[0].bar(msft.iloc[:, 0], msft.iloc[:, 5]) axs[1].plot(msft.iloc[:, 0], msft.iloc[:, 6]) fig.autofmt_xdate() ############################################################################### +# Using numpy +# =========== -# Unlabeled data. fname2 = cbook.get_sample_data('data_x_x2_x3.csv', asfileobj=False) with cbook.get_sample_data('data_x_x2_x3.csv') as file: array = np.loadtxt(file) -# Labeling, if no names in csv-file. +############################################################################### +# Labeling, if no names in csv-file +# --------------------------------- + +# Deprecated: plt.plotfile(fname2, cols=(0, 1, 2), delimiter=' ', names=['$x$', '$f(x)=x^2$', '$f(x)=x^3$']) +# Use instead: fig, axs = plt.subplots(2, sharex=True) axs[0].plot(array[:, 0], array[:, 1]) axs[0].set(ylabel='$f(x)=x^2$') axs[1].plot(array[:, 0], array[:, 2]) axs[1].set(xlabel='$x$', ylabel='$f(x)=x^3$') -# More than one file per figure--illustrated here with a single file. +############################################################################### +# More than one file per figure +# ----------------------------- + +# For simplicity of the example we reuse the same file. +# In general they will be different. +fname3 = fname2 + +# Depreacted: plt.plotfile(fname2, cols=(0, 1), delimiter=' ') -plt.plotfile(fname2, cols=(0, 2), newfig=False, - delimiter=' ') # use current figure +plt.plotfile(fname3, cols=(0, 2), delimiter=' ', + newfig=False) # use current figure plt.xlabel(r'$x$') plt.ylabel(r'$f(x) = x^2, x^3$') +# Use instead: fig, ax = plt.subplots() ax.plot(array[:, 0], array[:, 1]) ax.plot(array[:, 0], array[:, 2])