BenT
BenT

Reputation: 3200

Moving contour labels after limiting plot size

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()

enter image description here

enter image description here

Upvotes: 2

Views: 1533

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339570

You may create the contour plot with limited data, such that the clabels 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()

enter image description here

Upvotes: 4

Related Questions