How to remove contour/ path inside ploygon on basemap using matplotlib?

会有一股神秘感。 提交于 2019-12-11 07:31:16

问题


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...

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.

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.


回答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:

, the original is:

, which brings the labels there.



来源:https://stackoverflow.com/questions/36578628/how-to-remove-contour-path-inside-ploygon-on-basemap-using-matplotlib

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!