Reputation: 3200
I am having issues with the contour labels in pyplot. When I limit the domain of the plot, the contour labels are written in parts of the plot that are no longer there. In some of the figures using real data this means that very few of the lines actually have labels. Is there an easy way to make sure that all the labels show up on the zoomed in plot?
The actual data this corresponds to is not regularly spaced and I will be using this on several different variables. I know that I can use the manual option but that means knowing which contours are in the domain that I choose.
For example, in the below example the 8000 contour label is missing in the second plot.
import numpy as np
from matplotlib import pyplot as plt
#Make some Fake Data
x = np.arange(-100,101,1)
x,y = np.meshgrid(x,x)
z = x**2+y**2+6*x
#Plot said fake data
ax = plt.subplot(111)
clevs = np.arange(0,z.max(),2000)
cs = ax.contour(x,y,z,clevs,colors='k')
plt.clabel(cs,inline=True,fmt='%3.0d')
plt.show()
#Plot zoomed in fake data
ax = plt.subplot(111)
clevs = np.arange(0,z.max(),2000)
cs = ax.contour(x,y,z,clevs,colors='k')
ax.set_xlim(-50,50) #Limit the x-axis
plt.clabel(cs,inline=True,fmt='%3.0d')
plt.show()
Upvotes: 2
Views: 1533
Reputation: 339570
You may create the contour plot with limited data, such that the clabel
s are forced to be in within the data range and hence show up in the plot. This can be done with masked numpy arrays as follows
import numpy as np
from matplotlib import pyplot as plt
x = np.arange(-100,101,1)
x,y = np.meshgrid(x,x)
z = x**2+y**2+6*x
ax = plt.subplot(121)
clevs = np.arange(0,z.max(),2000)
cs = ax.contour(x,y,z,clevs,colors='k')
plt.clabel(cs,inline=True,fmt='%3.0d')
#Plot zoomed in fake data
ax2 = plt.subplot(122)
clevs = np.arange(0,z.max(),2000)
def limitcontour(ax, x,y,z,clevs, xlim=None, ylim=None, **kwargs):
mask = np.ones(x.shape).astype(bool)
if xlim:
mask = mask & (x>=xlim[0]) & (x<=xlim[1])
if ylim:
mask = mask & (y>=ylim[0]) & (y<=ylim[1])
xm = np.ma.masked_where(~mask , x)
ym = np.ma.masked_where(~mask , y)
zm = np.ma.masked_where(~mask , z)
cs = ax.contour(xm,ym,zm, clevs,**kwargs)
if xlim: ax.set_xlim(xlim) #Limit the x-axis
if ylim: ax.set_ylim(ylim)
ax.clabel(cs,inline=True,fmt='%3.0d')
limitcontour(ax2, x,y,z, clevs, xlim=[-50,50], ylim=[-90,90], colors="k")
ax.set_title("all data")
ax2.set_title("masked data")
plt.show()
Upvotes: 4