1

I was hoping to create a function that will set the x axis limit for a plot. Here is what is working currently:

import matplotlib.pyplot as plt

def scatter_plot(df, user_conditions):
    data_to_plot = user_conditions['data_to_plot']
    title = data_to_plot.replace("_", " ").title()
    df1 = df[['time',data_to_plot]]
    df1 = index_dataframe_time(df1)
    plt.scatter(df1.index.to_pydatetime(), df1[data_to_plot])
    min = df1.index.min()
    max = df1.index.max()
    plt.xlim(min, max)
    plt.title('Hour of Day vs '+title, fontsize=14)
    plt.show()

Here is what I was hoping for:

def scatter_plot(df, user_conditions):
    data_to_plot = user_conditions['data_to_plot']
    title = data_to_plot.replace("_", " ").title()
    print title
    df1 = df[['time',data_to_plot]]
    df1 = index_dataframe_time(df1)
    plot = plt.scatter(df1.index.to_pydatetime(), df1[data_to_plot])
    plot = set_limits(df1, plot)
    plot.title('Hour of Day vs '+title, fontsize=14)
    plot.show()

def set_limits(df, plot):
    min = df.index.min()
    max = df.index.max()
    plot.xlim(min, max)
    return plot

However, there is an issue in set_limits with plot.xlim(min,max),

> Traceback (most recent call last):   
File
> "C:/Users/Application/main.py", line 115, in <module>
>     
main()   
> 
> File "C:/Users/Application/main.py", line
> 106,
> in main
>     plot_configuration(df, user_conditions)   File "C:/Users/Application/main.py", line 111,
> in plot_configuration
>     scatter_plot(df, user_conditions)   
File "C:/Users/Application/main.py", line 76,
> in scatter_plot
>     plot = set_limits(df1, plot)   File "C:/Users/Application/main.py", line 83,
> in set_limits
>     plot.xlim(min, max) AttributeError: 'PathCollection' object has no attribute 'xlim'

How can set_limits be modified in order to fix this?

4
  • How did you import matplotlib? e.g. where does plt come from? Commented Dec 23, 2015 at 19:58
  • @mgilson Sorry about that, question is now fixed to reflect that Commented Dec 23, 2015 at 20:03
  • 1
    The problem is that pyplot is a stateful module which is meant to be convenient for people who are used to matlab. In particular, the statefulness is why plt.set_xlim works -- pyplot has a reference to the figure (and axes) that you're currently working with. If you want to work with the plots themselves, this doesn't work (well) and you'll need to use the object oriented interface provided by matplotlib.figure. reference. I suppose you could use pyplot.gcf() to get the current figure ... Commented Dec 23, 2015 at 20:07
  • The problem is that the object passed into the set_limits function as written as used is the Collection artist returned by scatter which does not have any notion of limits. Commented Dec 23, 2015 at 22:29

1 Answer 1

3

You probably want to be doing something like this:

import matplotlib.pyplot as plt

def scatter_plot(ax, df, user_conditions):
    """
    Parameters
    ----------
    ax : matplotlib.axes.Axes
        The axes to put the data on
    df : pd.DataFrame
        The data
    user_conditions : dict (?)
        bucket of user input to control plotting?
    """
    data_to_plot = user_conditions['data_to_plot']
    title = data_to_plot.replace("_", " ").title()
    print(title)
    df1 = df[['time',data_to_plot]]
    df1 = index_dataframe_time(df1)
    # sc = ax.scatter(df1.index.to_pydatetime(), df1[data_to_plot])
    # only works in 1.5.0+
    sc = ax.scatter(df1.index.to_pydatetime(), data_to_plot,
                    data=df)
    set_limits(df1, ax)
    ax.set_title('Hour of Day vs '+title, fontsize=14)

    return sc

def set_limits(df, ax):
    min = df.index.min()
    max = df.index.max()
    ax.set_xlim(min, max)


fig, ax = plt.subplots()
arts = scatter_plot(ax, df, user_conditions)

if you are not varying the size or color of the markers you are better off using ax.plot(..., linestile='none', marker='o') which will render faster. In this case something like (if you have 1.5.0+)

ax.plot(data_to_plot, linestyle='none', marker='o', data=df)

and it should 'do the right thing'.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.