-
-
Notifications
You must be signed in to change notification settings - Fork 18.6k
DOC/VIS: plotting on current figure/axis with Series/DataFrame.plot() #8776
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is something that's always bothered me a bit. I don't think there's a good reason for Series and DataFrame to behave differently. |
Just to be clear, |
Personally I think both should follow DataFrame behaviour of creating a new figure unless ax is explicitly passed. Like tacaswell says, pyplot works based on the currently active axis but once you start dealing with multiple axes, it's much nicer to use the object-oriented approach to creating figures and axes, and pass them explicitly to plotting functions. As it is, import pandas as pd
import matplotlib.pyplot as plt
s = pd.Series([4, 5, 6, 7, 8, 9])
# x-axis runs from 0-2
plt.plot([1, 2, 3])
# not anymore!
s.plot()
plt.show() |
The advantage of targeting the 'current axes', rather than making a new figure is that it lets you easily plot multiple lines to the same axes (which something at least I frequently do) without forcing the users to start using the OO api. |
Agreed to let
|
Strongly disagree with the suggestions to make Series behave like the current DataFrame implementation and would much rather have it the other way around. As a frequent user of pandas/mpl in interactive work, I seldom want to have to deal with the OO interface, and not having a default behavior of using plt.gcf()/gca() in what's supposed to be a convenience method makes it much less useful. Also, for what it's worth, the current behavior is a change from the old behavior in pandas 0.13.x: |
From my perspective, the Series behavior of plotting on gca is super useful for interactive work, and I really don't want to get rid of that. I see Series/DataFrame.plot as being mainly for quick and dirty plots, which are usually done interactively. When I need to refine somethingI turn to seaborn / matplotlib and use the OO interface. So I guess what I'm saying is
|
This is speaking wearing my not-mpl-dev hat, this is not the settled plan of mpl. One of the things I have been thinking about (but have not fully fleshed out yet) is having mpl provide a decorator/registration function as part of def pandas_plotting_func(ax, df_or_ds, bunch_of_style):
ax.foo in pandas and then to provide interactive plotting you would do something like plt.register_func(pdplot.pandas_plotting_func)
plt.pandas_plotting_func(df, ...)
plt.pandas_plotting_func(df, ..., ax=ax1) would all work as expected. The register function would look something like def register_func(func):
@wraps(func)
def inner(*args, **kwargs):
if 'ax' in kwargs:
ax = kwargs.pop('ax', None)
elif len(args) > 0 and isinstance(args[0], matplotlib.axes.Axes):
ax = args[0]
args = args[1:]
else:
ax = plt.gca()
ret = func(ax, *args, **kwargs)
ax.figure.canvas.draw() # possible perf hit
return ret
# magic to insert function into pyplot namespace
return inner That way you can get the best of both worlds, have quick and dirty interactive plotting and be able to re-use those same functions embedded in larger applications. I would also like to rip most of the core plotting off of the |
I agree with @TomAugspurger here that the Series behaviour is certainly usefull for interactive plotting, so I wouldn't change that either. |
I completely agree with this. I find it so annoying when I do something like
and nothing appears from an interactive IPython session (except
to make a window appear. Similarly when goign exploatory work, I often write things like
and then nothing. Which leaves me with the options of going back to
|
Your plot in being dumped into your currently open figure. You may need a call to |
The problem with this process is that |
Pandas is importing pyplot under the hood no matter what. The pyplot interface is for exploratory work (as opposed to the OO On Tue, Feb 24, 2015, 22:23 Kevin Sheppard [email protected] wrote:
|
I understand - my only gripe here is that it should not be necessary to explicitly |
I too am in the camp of finding it annoying that a Series does not open a plot window on it's own. Pandas is extraordinary helpful for exploratory data analysis and I just don't see the logic behind having a DataFrame opening a new figure just fine and a Series, which in terms of the data analyst is just another column, would NOT do that. I feel that this throws me off all the time, it just does not make any sense to me, so I would to see this discussed more on both the MPL and Pandas point of views, to help me make sense of it. |
I agree that the inconsistent behavior for .plot() is a gotcha. Personally, I like the DataFrame behavior. Plotting on the same axes is straight forward and intuitive:
As opposed to Series, which, with the current behavior, requires to the non-intuitive
At a minimum, the documentation should be amended: Series.plot() |
Responding (very late) to @michaelaye it 'works' with inline because it does not keep live figures around, thus the next call to |
From SO, I noticed that
Series.plot()
plots on the current axis if no ax is specified, andDataFrame.plot
not (so creates a new figure when no ax is specified).Some things about this:
Series.plot()
mention this onax
: "If not passed, uses gca()", while the docs forDataFrame.plot()
don't say thisSo, if this is deliberate, we should:
DataFrame.plot()
(now nothing is said about this)plt.figure()
calls from the documentation, as these have no effect (eg second plot here: http://pandas.pydata.org/pandas-docs/stable/visualization.html#basic-plotting-plot). This is what caused the confusion on SO.or if not:
DataFrame.plot()
also first tries to get the current axis withgca
@TomAugspurger @sinhrks
The text was updated successfully, but these errors were encountered: