Setup a graph using matplotlib which is working properly (see image below), but when I try to add a legend I get the following error: UserWarning: No labeled objects found. Use label='...' kwarg on indivial plots.
Here's the code I'm using to define the lines that I want in the legend and draw the legend:
#Moving average labels
smaLabel1 = str(SMA1)+'d SMA'
smaLabel2 = str(SMA2)+'d SMA'
smaLabel3 = str(SMA3)+'d SMA'
#Add SMAs to chart
ax1.plot(ind, avg1, '#5998ff', label=smaLabel1, linewidth=1)
ax1.plot(ind, avg2, '#ffbb82', label=smaLabel2, linewidth=1)
ax1.plot(ind, avg3, '#d689c4', label=smaLabel3, linewidth=1)
""" End SMA additions """
#Add legend
plt.legend()
I've checked the smaLabel variables, and all hold the correct strings. Anyone know why the labels aren't registering?
You must have plot the candle plots and the volume before plotting the SMA. The candle plot doesn't have any labeled object, when you call the plt.legend(), it tries to plot a label for every plot on the current axes. Therefore, you get this UserWarning: No labeled objects found. Use label='...' kwarg on indivial plots.
To solve it, I hope it is clear at this point, simply requires you to plot the SMA's very first, before the candle plot, and call the legend() right after that before any other plots being generated.
Related
I am currently working with some geospatial data and I want to add a colorbar next to the map. I used the following code to overlay a baseline map with a scatter plot. However, I cannot get the correct colorbar next to it. Can anyone find the reason for such behaviour?
cm = plt.cm.get_cmap('RdYlBu') # define a colormap
fig,ax = plt.subplots(figsize=(15, 15))
city_map = df.plot(alpha=0.2, ax=ax) # plot a city contour
ctx.add_basemap(city_map) # plot a city map
points = gdf_new.plot(c=gdf_new['Score'], cmap=cm, ax=ax) # scatter plot
fig.colorbar(ax.collections[1], ax=ax) # current solution
pandas column gdf_new['Score'] contains values from 0 to 1 used for points coloring.
If I replace the last line with below, I get:
for plt.colorbar() - RuntimeError: No mappable was found to use for colorbar creation. First define a mappable such as an image (with imshow) or a contour set (with contourf)
for plt.colorbar(point) - AttributeError: 'AxesSubplot' object has no attribute 'get_array'
My current solution is to add:
fig.colorbar(ax.collections[1], ax=ax) - it displays the correct color bar but with a wrong numbers' range of 0-200 instead 0-1.
How to fix it?
I have created two line plots with this dataset. The first lineplot shows the number of flight accidents in a given year. The second lineplot shows the number of fatalities in a given year. I want to put both line plots on the same graph. This is the code I have used:
fatalities=df[['Fatalities','Date']]
fatalities['Year of Fatality']=fatalities['Date'].dt.year
fatalities.drop('Date',inplace=True)
fatalities.set_index('Year of Fatality',inplace=True)
fatalities.sort_index(inplace=True)
plt.figure(figsize=(12,9))
plt.title("Number of Flight Accidents Since 1908",fontsize=20)
plt.ylabel("Number of Flight Accidents")
plt.xlabel("Year")
plt.xticks(year.index,rotation=90)
year.plot()
fatalities.plot()
plt.show()
What I get are two plots, with on above the other: the plot which shows the number of fatalities and the plot which shows the number of flight accidents.
What I want is one graph that shows the two line plots. Any help would be much appreciated. (Side note: how can I rotate the xticks 90 degrees? I used the rotation argument in the plt.xticks() but this had zero affect).
Given the use of .plot() and variables called df, I assume you're using pandas dataframes (if that's not the case, the answer still probably applies, look up the docs for your plot function).
Pandas' plot by default puts the plots in their own axis, unless you pass one to draw on via the ax attribute:
fig, ax = plt.subplots()
year.plot(ax=ax)
fatalities.plot(ax=ax)
I have a function which plots and displays the distribution using the distplot from seaborn. it looks like this
def getPlot(data):
x=sns.distplot(data, hist=False)
plt.show()
return x
every time I call the function I get a plot of the distribution.
I want some help in modifying the function so that at the end of calling the function multiple times I should get an extra plot which is the combination of all the previous plots.
So if my function calls were
getPlot(data1)
getPlot(data2)
getPlot(data3)
I should get the individual plots for the data as I call the function and also at the very end I want the plots for the 3 data to be superimposed on each other.
Just moving plt.show() outside the function will not suffice because I want individual plots of the separate data as well as one figure that contains all the data.
Since you have to keep both a separate plot and a joint one of your data you have to plot each dataset twice. Once in a separate axes and once in a common one.
What I would do is create a figure and an axes into which everything will be plotted together. Then pass that axes object into the function, and make the function plot into the axes as well as into a new figure:
def plot_twice(data, ax_all):
# first plot into the common axes
sns.distplot(data, hist=False, ax=ax_all)
# and create a new figure and axes for a standalone plot
fig,ax = plt.subplots()
x = sns.distplot(data, hist=False, ax=ax)
return x
# create axes for the common plot
fig,ax_all = plt.subplots()
# now plot the things
getPlot(data1, ax_all)
getPlot(data2, ax_all)
getPlot(data3, ax_all)
# only call blocking plt.show() at the end
plt.show()
It doesn't seem feasible to copy plots from one axes to the other with matplotlib (see e.g. this or this), so unless the plotting takes an excessive amount of time or memory I'd just plot the data twice for simplicity.
I am attempting to save a plot in "layers". First I want to save just the grid. Then I want to save just my scatter points. And finally I want to save just my trend line, but I can't figure out how to "turn off" my scatter points to do this. My reasoning for doing this is so that I can import each component of the graph as a layer in photoshop.
Here's my code:
FIRST PLOT GRID ONLY
fig=plt.figure()
ax1=fig.add_subplot(111)
#ax1.plot(x,p(x), linewidth=3.0, color="#daa004")
plt.ylim(top=72)
plt.ylim(bottom=60)
plt.xlim(right=2025)
plt.xlim(left=1895)
plt.grid(axis='x', alpha=0.4)
plt.grid(axis='y', alpha=0.4)
plt.savefig('MeanAnnualFallTMAX_Grid.png', transparent=True)
PLOT SCATTER ONLY
ax1.plot(x,y,'o',markersize=3,color="#daa004",label="Annual Mean Fall Maximum Temperature")
plt.axis('off')
plt.savefig('MeanAnnualFallTMAX_Scatter.png', transparent=True)
PLOT TREND ONLY (The problem)
ax1.plot(x,p(x), linewidth=3.0, color="#daa004")
plt.axis('off')
plt.savefig('MeanAnnualFallTMAX_Trend.png', transparent=True)
But this prints the scatter and the trend. Is there a way to "clear" or "turn-off" the scatter points I previously plotted?
if you save a reference to your line you may either
Turn the points invisible
line, = ax1.plot(x,y,'o')
# ...
line.set_visible(False)
Remove the points from the axes
line, = ax1.plot(x,y,'o')
# ...
line.remove()
I think for this workflow I'd at least try to save the figure as svg and open this in Inkscape. Ungrouping the results there gives access to every partof the figure.
However, it'll soon be divided into too small pieces like points or lines, but have a look - perhaps it helps.
I need to fit a function to a large number of datasets stored in several files and compare the fits. I open a file, read the columns and plot each fit as a subplot after fitting. Eventually I have a figure with lot of subplots showing all the fits. However, I need to see the fit and also the residual for each subplot like in the figure.
So far, I have the following. I thought I could add axes to subplot but it does not work. The function that I have works. But I do not know how to add axes to subplot to plot the residual with the fit as a subplot to the subplot.
def plotall(args):
x=args[0]
ydata=args[1]
chisq=args[2]
fit=args[3]
g1=args[4]
a=args[5]
ptitle=args[6]
axi = fig1.add_subplot(a1,b1,a+1)
axi.plot(x, ydata,'ko',markersize=2,label='Data')
axi.plot(x,fit,'m-',label='Fit')
axi.text(0.75,0.8,'T=%4.1f(K)'%ptitle, fontsize=7,transform = axi.transAxes)
axi.text(0.05,0.45,r'$\chi^2$=%3.1f'%chisq,fontsize=7,transform = axi.transAxes)
ytlist=np.linspace(min(ydata),max(ydata),4)
axi.set_yticks(ytlist)
axi.set_xlim([xlow,xhi])
xtlist=np.linspace(xlow,xhi,6)
axi.set_xticks(xtlist)
for label in (axi.get_xticklabels() + axi.get_yticklabels()):
label.set_fontname('Arial')
label.set_fontsize(5)
axi.legend(('Data','Fit'), 'upper left', shadow=False, fancybox=False,numpoints=1,
frameon = 0,labelspacing=0.01,handlelength=0.5,handletextpad=0.5,fontsize=6)