Search code examples
matplotliberror-handlingaxis-labels

Matplotlib Error: 'str' object has no attribute 'get_figure'


I have code that looks like this below and I'm getting an error that I don't understand on the line with ltycs.plot(ax='time'):

#PRODUCE AND VISUALIZE FORECAST
pred_uc = results.get_forecast(steps=12-cm+1) # forecast steps in terms of "y" which is months
pred_ci = pred_uc.conf_int()
import matplotlib.dates as mdates
#from matplotlib.dates import MonthLocator
ax = y['2020':].plot(label='observed', figsize=(14, 7)) #crop of blue or "observed" val in final plot 
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
pred_uc.predicted_mean.plot(ax=ax, label='Forecast')
ax.fill_between(pred_ci.index,
                pred_ci.iloc[:, 0],
                pred_ci.iloc[:, 1], color='k', alpha=.25)
#ax.set_xlabel('Date')
ax.set_ylabel('MOS Wind Speed')
#add the LT monthly average to plot
lty = ylt.groupby(ylt.index.month).mean()
lty = lty.to_frame() 
lty.columns=['LT Mean']
ltyc = lty.iloc[0:12].reset_index() # extract curr month to end of LT mean monthly wind speed
#create date sequence using date format of df = y
ltyc['time'] = pd.to_datetime(ltyc["time"], format='%m').apply(lambda, 
dt:dt.replace(year=2020))#convert the "Date" col to yyyy-mm-dd 
ltycs = pd.Series(ltyc['LT Mean'].values, index=ltyc['time'])#convert to Series for plot
ltycs.plot(label='LT Mean',ax=ax,color='k')#ax='time' plots x months
ltycs.plot(ax='time')
plt.grid(b=True, which='major', color='k', linestyle='-')
plt.grid(b=True, which='minor', color='g', linestyle='-', alpha=0.2)#alpha is the minor grid 
plt.minorticks_on()
plt.legend()
plt.show()

The var "ltycs" is a pandas series and looks like this:

ltycs
Out[382]: 
time
2020-01-01    7.411365
2020-02-01    7.193070
2020-03-01    7.397183
2020-04-01    7.684527
2020-05-01    7.670577
2020-06-01    7.348572
2020-07-01    6.898480
2020-08-01    6.852384
2020-09-01    7.250651
2020-10-01    7.681693
2020-11-01    7.587329
2020-12-01    7.444730
dtype: float64

I'm getting the result in the plot that I'm looking for with months along the x axis but the program stops on this error -

File "C:\Users\U321103\AppData\Local\Continuum\anaconda3\envs\Stats\lib\site- 
packages\pandas\plotting\_matplotlib\core.py", line 323, in _setup_subplots
fig = self.ax.get_figure()

AttributeError: 'str' object has no attribute 'get_figure'

Here is my plot and it looks as expected after assigning the 'time' column or months to the x axis. Thank you!

enter image description here


Solution

  • After you answer in the comments on the purpose of the problematic ltycs.plot(ax='time') line:

    It's this line ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m')) that does what you describe (i.e. displaying months in the xaxis). Plotting a pandas.DataFrame, ax parameter expects a matplotlib axes object, not a string, which is why you're getting an error. The reason you get correct labeling when you include the problematic line is - you don't run plt.minorticks_on() call.

    So, what you should do, is first and foremost, create a matplotlib axis via matplotlib subplots, then set minorticks_on and then plot pandas.DataFrames, passing the matplotlib ax object to their respective plot functions as:

    #PRODUCE AND VISUALIZE FORECAST
    pred_uc = results.get_forecast(steps=12-cm+1) # forecast steps in terms of "y" which is months
    pred_ci = pred_uc.conf_int()
    import matplotlib.dates as mdates
    #from matplotlib.dates import MonthLocator
    figure, ax = plt.subplots(figsize = (14,7))
    plt.minorticks_on()
    y['2020':].plot(label='observed', ax = ax)
    pred_uc.predicted_mean.plot(ax=ax, label='Forecast')
    ax.fill_between(pred_ci.index,
                    pred_ci.iloc[:, 0],
                    pred_ci.iloc[:, 1], color='k', alpha=.25)
    #ax.set_xlabel('Date')
    ax.set_ylabel('MOS Wind Speed')
    #add the LT monthly average to plot
    lty = ylt.groupby(ylt.index.month).mean()
    lty = lty.to_frame() 
    lty.columns=['LT Mean']
    ltyc = lty.iloc[0:12].reset_index() # extract curr month to end of LT mean monthly wind speed
    #create date sequence using date format of df = y
    ltyc['time'] = pd.to_datetime(ltyc["time"], format='%m').apply(lambda, 
    dt:dt.replace(year=2020))#convert the "Date" col to yyyy-mm-dd 
    ltycs = pd.Series(ltyc['LT Mean'].values, index=ltyc['time'])#convert to Series for plot
    ltycs.plot(label='LT Mean',ax=ax,color='k')#ax='time' plots x months
    ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
    plt.grid(b=True, which='major', color='k', linestyle='-')
    plt.grid(b=True, which='minor', color='g', linestyle='-', alpha=0.2)#alpha is the minor grid 
    plt.legend()
    plt.show()