I am trying to create a graphic where I overlay multiple contour plots on a single image. So I want to have colorbars for each of the plots, as well as a legend indicating what each contour represents. However Matplotlib will not allow me to create a separate legend for my contour plots. Simple example:
import matplotlib as mpl
import matplotlib.pyplot as plt
import cartopy
import cartopy.crs as ccrs
import numpy as np
def create_contour(i,j):
colors = ["red","green","blue"]
hatches = ['-','+','x','//','*']
fig = plt.figure()
ax = plt.axes(projection=ccrs.PlateCarree())
ax.set_extent((-15.0,15.0,-15.0,15.0))
delta = 0.25
x = np.arange(-3.0,3.0,delta)
y = np.arange(-2.0,2.0,delta)
X, Y = np.meshgrid(x, y)
data = np.full(np.shape(X), 1.0)
plot = ax.contourf(X,Y,data, levels = [float(i),float(i+1)], hatch=[hatches[j]], colors = colors[i], label="label")
plt.legend(handles=[plot], labels=["label"])
plt.savefig("figure_"+str(i)+".png")
create_contour(1,3)
When I run this, I get the following message:
UserWarning: Legend does not support (matplotlib.contour.QuadContourSet object at 0x7fa69df7cac8) instances. A proxy artist may be used instead. See: http://matplotlib.org/users/legend_guide.html#creating-artists-specifically-for-adding-to-the-legend-aka-proxy-artists "aka-proxy-artists".format(orig_handle)
But as far as I can tell, I am following those directions as closely as possible, the only difference being that they do not use contourf in the example.
Any help would be greatly appreciated.
The comments to your question look like they have solved the question (by making custom patches and passing those through to the legend). There is also an example that I added many years ago to the matplotlib documentation to do something similar (about the same time I added contour hatching to matplotlib): https://matplotlib.org/examples/pylab_examples/contourf_hatching.html#pylab-examples-contourf-hatching
It is such a reasonable request that there is even a method on the contour set to give you legend proxies out of the box: ContourSet.legend_elements.
So your example might look something like:
%matplotlib inline
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import numpy as np
fig = plt.figure(figsize=(10, 10))
ax = plt.axes(projection=ccrs.PlateCarree())
ax.coastlines('10m')
y = np.linspace(40.0, 60.0, 30)
x = np.linspace(-10.0, 10.0, 40)
X, Y = np.meshgrid(x, y)
data = 2*np.cos(2*X**2/Y) - np.sin(Y**X)
cs = ax.contourf(X, Y, data, 3,
hatches=['//','+','x','o'],
alpha=0.5)
artists, labels = cs.legend_elements()
plt.legend(handles=artists, labels=labels)
plt.show()