首页 文章

如何使用matplotlib删除底图上ploygon内的轮廓/路径?

提问于
浏览
1

我正在处理一些天气数据,使用matplotlib在底图上绘制轮廓线 . 我使用的数据(x,y和数据)在这里上传http://www.mediafire.com/download/0epjjdm8auit611/mslp.txt这里http://www.mediafire.com/download/1dn6p8nw96h2mmd/xlong.txt和这里http://www.mediafire.com/download/31suzsz6j7u2bgz/xlat.txt . 工作示例代码如下: -

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

上面的代码给了我以下情节......

enter image description here

情节绝对可以 . 但我想隐藏/删除特定区域的轮廓线 . 因此,我在底图上绘制了一个多边形,并尝试隐藏多边形下方的数据 . 我用来做的代码如下: -

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

得到的图像如下所示 . 如您所见, facecolour 没有效果,因为它不会隐藏它下面的任何数据 .

enter image description here

我想要做的是删除通过此多边形的轮廓线或使用图像处理技术隐藏/剪切多边形区域 .

我想到的解决方案是: -

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.

我的思想并没有超越上述想法 . 任何解决此问题的解决方案都非常受欢迎 .

1 回答

  • 1

    matplotlib的Basemap工具包遵循与matplotlib本身相同的大部分逻辑 . 你会注意到你有zorder参数给你的情节调用 . 您只需要确保矩形的zorder高于轮廓的 zorder .

    最近我给了一个类似问题here的awnser . 代码逻辑应该是可重现的,例如:

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

    ,请注意 axvspanplot 数据本身如何被强制置于 grid 之上(通过修补 zorder ) .

    EDIT: 具有低于矩形的zorder的等高线图的工作示例 .

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

    ,结果是:

    Rectangle overlapping countour plot

    ,原文是:

    contour plot

    ,它带来了标签 .

相关问题