1

I am working with some weather data to plot contour lines on basemap using matplotlib. The data I have used (x, y and data) is uploaded here http://www.mediafire.com/download/0epjjdm8auit611/mslp.txt here http://www.mediafire.com/download/1dn6p8nw96h2mmd/xlong.txt and here http://www.mediafire.com/download/31suzsz6j7u2bgz/xlat.txt. The working example code is below:-

from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon

m = Basemap(projection='merc', llcrnrlat=7, urcrnrlat=40,
            llcrnrlon=68, urcrnrlon=110, resolution='l')

x = np.loadtxt('xlong.txt', delimiter=',')
y = np.loadtxt('xlat.txt', delimiter=',')
Z = np.loadtxt('mslp.txt', delimiter=',')

x, y = m(x, y)
CS = plt.contour(x, y, Z, colors='b')

plt.show()

The above code gives me the following plot...

enter image description here

The plot is absolutely OK. But I would like to hide/ remove contour lines over a particular area. So, I have drawn a polygon over a basemap and tried to hide data beneath the polygon. The code I have used for doing is as follows:-

from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon


def draw_screen_poly(lats, lons, m):
    x, y = m(lons, lats)
    xy = zip(x, y)
    poly = Polygon(xy, facecolor='red')
    plt.gca().add_patch(poly)

lats = [30, 35, 35, 30]
lons = [80, 80, 90, 90]

m = Basemap(projection='merc', llcrnrlat=7, urcrnrlat=40,
            llcrnrlon=68, urcrnrlon=110, resolution='l')

x = np.loadtxt('xlong.txt', delimiter=',')
y = np.loadtxt('xlat.txt', delimiter=',')
Z = np.loadtxt('mslp.txt', delimiter=',')

x, y = m(x, y)
CS = plt.contour(x, y, Z, colors='b')

draw_screen_poly(lats, lons, m)

plt.show()

The resulting image is lloking like below. As you can see, there is no effect of facecolour as it does not hide any data beneath it.

enter image description here

What I want to do is either remove contour lines passing through this polygon or hide/ clip the polygon area using image processing technique.

The solution I think of are:-

1. Apply some white colour to polygon region so that it matches the basemap colour and data is hidden (this is already done in the above example and does not work).

2. Go through each contour from contour collection and check if it is passing through the polygon region. Finally remove it from plot.

3. Finally, Chip off the polygon area.

My mind is not proceeding beyond above ideas. Any solution to solve this issue is highly appreciated.

sundar_ima
  • 3,604
  • 8
  • 33
  • 52

1 Answers1

1

The Basemap toolkit for matplotlib follows most of the same logic as matplotlib itself. You'll notice that you have zorder arguments to give to your plot calls. You just need to make sure that the zorder of the rectangle is higher than the zorder of the contour.

Recently I've given an awnser for a similar question here. The code logic should be reproducible for you example:

import numpy as np
import matplotlib.pyplot as plt

t = np.arange(-1, 2, .01)
s = np.sin(2*np.pi*t)

plt.plot(t, s,zorder=4)

p = plt.axvspan(1.25, 1.55, facecolor='g', alpha=1,zorder=3)

plt.axis([-1, 2, -1, 2])
plt.grid(zorder=2)

plt.show()

, notice how the axvspan and the plot data itself is forced to be on top of the grid (by tinkering with the zorder).

EDIT: Working example of contour plot with lower zorder than a rectangle.

import matplotlib
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt

matplotlib.rcParams['xtick.direction'] = 'out'
matplotlib.rcParams['ytick.direction'] = 'out'

delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians
Z = 10.0 * (Z2 - Z1)


# Create a simple contour plot with labels using default colors.  The
# inline argument to clabel will control whether the labels are draw
# over the line segments of the contour, removing the lines beneath
# the label
fig = plt.figure()
ax = fig.add_subplot(111)
CS = plt.contour(X, Y, Z,zorder=3)
plt.clabel(CS, inline=1, fontsize=10)
plt.title('Simplest default with labels')

rect1 = matplotlib.patches.Rectangle((0,0), 2, 1, color='yellow',zorder=5)

ax.add_patch(rect1)

plt.show()

, which results in:

Rectangle overlapping countour plot

, the original is:

contour plot

, which brings the labels there.

Community
  • 1
  • 1
armatita
  • 12,825
  • 8
  • 48
  • 49
  • Thank you very much. That worked. However, I have also have `clabel` for each contour lines. there is no effect on zorder on `clabel`. Any idea to remove this as well? – sundar_ima Apr 12 '16 at 16:45
  • @sundar_ima It's probably a problem with something on your code sequence since I can't reproduce your problem. As you see in my edited post the labels are below the rectangle. – armatita Apr 12 '16 at 17:05
  • Thant worked perfectly. Thank you very much. Accepting your answer. – sundar_ima Apr 12 '16 at 17:16