Matplotlib Plotting: AttributeError: 'list' object has no attribute 'xaxis' - python

Example Plot that needs to format date
I am trying to plot stock prices against time (see above). The code below does plot the "OPEN" prices but as I try to format the X-axis dates from ordinal to ISO dates, it throws AttributeError.
The same code worked while plotting the OHLC graph, but somehow this doesn't work now.
AttributeError: 'list' object has no attribute 'xaxis'
df_copy = read_stock('EBAY')
fig = plt.figure(figsize= (12,10), dpi = 80)
ax1 = plt.subplot(111)
ax1 = plt.plot(df_copy['Date'], df_copy['Open'], label = 'Open values' )
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))

This line:
ax1 = plt.plot(df_copy['Date'], df_copy['Open'], label='Open values')
Refines your Axes object to be the list of artists returned by the plot command.
Instead of relying on the state machine to put artists on the Axes, you should use your objects directly:
df_copy = read_stock('EBAY')
fig = plt.figure(figsize=(12, 10), dpi=80)
ax1 = fig.add_subplot(111)
lines = ax1.plot(df_copy['Date'], df_copy['Open'], label='Open values')
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))

The problem comes from you writing
ax1 = plt.plot(df_copy['Date'], df_copy['Open'], label = 'Open values' )
Since you are changing the type of ax1 from being the handle returned by plt.subplot(). After said line, it is a list of lines that were added to the plot, which explains your error message. See the documentary on the plot command:
Return value is a list of lines that were added.
matplotlib.org

Related

Remove colorbar from map plot

I have a plot of a map containing areas which are color coded. I need to remove the automatic color bar from the plot and replace with a legend. However, I cannot find a way to remove the color bar. Xarray was used to create the data array.
map_crs = ccrs.OSGB()
fig = plt.figure(figsize=(10, 15))
cmap = mpl.colors.ListedColormap(colours)
norm = mpl.colors.BoundaryNorm(boundaries=bins, ncolors=len(cmap.colors)-1 )
stamen_terrain = cigmt.Stamen('terrain')
ax = plt.axes(projection=stamen_terrain.crs)
data_array.plot(transform=map_crs, vmin=0, vmax=np.max(data_array), cmap=cmap)
plt.gca().coastlines()
plt.tight_layout()
plt.savefig(plotname, bbox_inches="tight", pad_inches=0.1)
plt.clf()
I have tried adding commands such as, colorbar=False, cbar=False, Colorbar=False. However, just continually receive the corresponding error;
AttributeError: 'QuadMesh' object has no property 'Colorbar'
Any ideas on how to get rid of the colorbar?
Done!
Just needed to put add_colorbar=False into the plotting command.
Now to add the legend!

Python plot sub plots with x as Index

I am trying to do a plot that uses sub plots in Python, but it doesn't seem to be working.
SO I have a dataframe and there is an Index. This index holds datetime. I have two columns that I would like to plot, and I am trying to use sub plots. Data1 and Data2 are my column names. My code is below
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.plot(x=df[index], y=df['Data1'])
ax2.plot(x=df[index], y=df['Data2'])
plt.show()
When I run this I get the following error.
TypeError: 'DataFrame' object cannot be interpreted as an integer

How do I stop the getting blank plots when trying to use Matplotlib's subplot feature?

I am currently working on some Vidhya articles. As part of following along, I'm running the following code:
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8,4))
ax1 = fig.add_subplot(121)
ax1.set_xlabel('Credit_History')
ax1.set_ylabel('Count of Applicants')
ax1.set_title("Applicants by Credit_History")
temp1.plot(kind='bar')
ax2 = fig.add_subplot(122)
temp2.plot(kind = 'bar')
ax2.set_xlabel('Credit_History')
ax2.set_ylabel('Probability of getting loan')
ax2.set_title("Probability of getting loan by credit history")
This is supposed to produce the following:
Correct answer from Vidhya
This seems straightforward enough. I understand the
However, when I attempt this, I have been getting this no matter how much I jiggle around with things.
What I'm getting
Obviously, this isn't right. My understanding of what is supposed to happen is:
I create a figure.
I specify that the figure will have two subplots, with the '121' and '122' specifying they will be horizontally adjacent to each other.
As I use the 'plot' command, the subplots should be utilized in the order they were generated.
Unfortunately, it seems like the code I am using is only utilizing ONE of the subplots, and then producing the other plot on a new line. I can not for the life of me figure out why this is the case.
While writing this I read some of 'Python for Data Analysis' and tried some new code to no avail. I've also attempted to print it this way with similar results:
fig, axes = plt.subplots(1, 2, figsize=(10, 8))
temp1.plot(kind='bar')
temp2.plot(kind='bar')
The code for temp1 and temp2 are as follows:
temp1 = df['Credit_History'].value_counts(ascending=True)
temp2 = df.pivot_table(values='Loan_Status',index['Credit_History'],aggfunc=lambda x: x.map({'Y':1,'N':0}).mean())
It seems that even if I print temp1 twice, the first subplot is blank for some reason. I'm really pretty stumped. The latter attempt to make it work is almost an exact copy of the code from 'Python for Data Analysis'.
You're not plotting in the axis that you want to. You need to tell Pandas which axis you want.
Try this:
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8, 4))
ax1 = fig.add_subplot(121)
ax1.set_xlabel('Credit_History')
ax1.set_ylabel('Count of Applicants')
ax1.set_title("Applicants by Credit_History")
temp1.plot(kind='bar', ax=ax1)
ax2 = fig.add_subplot(122)
ax2.plot(kind='bar')
ax2.set_xlabel('Credit_History')
ax2.set_ylabel('Probability of getting loan')
ax2.set_title("Probability of getting loan by credit history")
temp2.plot(kind='bar', ax=ax2)
Notice the ax kwarg in the plot methods.

matplotlib locator_params or set_major_locator not working

I am trying to reduce the number of axis ticks in subplots (each axis different values, so I can't set the ticks manually), but other answers such as this or this don't work.
My syntax for creating the figure is standard, as follows:
fig = plt.figure(figsize=(7,9))
ax = fig.add_subplot(8,2,i+1) # I am plotting in a much larger loop, but I don't think there is anything wrong with the loop, because everything else (axis limits, labels, plotting itself...) works fine.
and to reduce the number of yticks, I tried
ax = plt.locator_params(nbins=4, axis='y')
which raised the error TypeError: set_params() got an unexpected keyword argument 'nbins'
and I tried
ax.yaxis.set_major_locator(plt.MaxNLocator(4))
which gave the error AttributeError: 'NoneType' object has no attribute 'yaxis'
I don't understand why my subplot is considered to be a NoneType. I suspect this is the core of the problem, but all examples that I saw have the same structure, i.e.
fig = plt.figure()
ax = fig.add_subplot(111)
ax.yaxis.set_major_locator(plt.MaxNLocator(4))
and it should work. So why is my ax NoneType?
The problem is the line:
ax = plt.locator_params(nbins=4, axis='y')
locator_params does not return an Axes instance (in fact it doesn't return anything), so on this line you are reassigning ax to be None.
I think you want to change it to:
ax.locator_params(nbins=4, axis='y')
and then it should all work ok.

matplotlib: any way to get existing colorbars?

In matplotlib's object oriented style you can get the current axes, lines and images in an existing figure:
fig.axes
fig.axes[0].lines
fig.axes[0].images
But I haven't found a way to get the existing colorbars, I have to assign the colorbar a name when first creating it:
cbar = fig.colorbar(image)
Is there any way to get the colorbar objects in a given figure if I didn't assign them names?
The problem is that the colorbar is added as "just another" axis, so it will be listed with the 'normal' axes.
import matplotlib.pyplot as plt
import numpy as np
data = np.random.rand(6,6)
fig = plt.figure(1)
fig.clf()
ax = fig.add_subplot(1,1,1)
cax = ax.imshow(data, interpolation='nearest', vmin=0.5, vmax=0.99)
print "Before adding the colorbar:"
print fig.axes
fig.colorbar(cax)
print "After adding the colorbar:"
print fig.axes
For me, this gives the result:
Before adding the colorbar:
[<matplotlib.axes._subplots.AxesSubplot object at 0x00000000080D1D68>]
After adding the colorbar:
[<matplotlib.axes._subplots.AxesSubplot object at 0x00000000080D1D68>,
<matplotl ib.axes._subplots.AxesSubplot object at 0x0000000008268390>]
That is, there are two axes in your figure, the second one is the new colorbar.
Edit: Code is based on answer given here:
https://stackoverflow.com/a/2644255/2073632

Categories

Resources