Python 3.x 如何在cartopy';使用python创建geoaxes?

Python 3.x 如何在cartopy';使用python创建geoaxes?,python-3.x,matplotlib,cartopy,Python 3.x,Matplotlib,Cartopy,我正在尝试为cartopy matplotlib绘图实现斑马样式 这是用于生成地理地图的常用打印样式。一些地理信息系统已经实现了这种方式。然而,Python并不拥有它 我已经成功地生成了一个函数,可以在给定的cartopy的GeoAxis中添加斑马状的蜱虫 尽管如此,尽管我努力更新算法,但我无法允许自动更新斑马蜱的坐标。此更新将允许解决诸如event.callbacks.connect操作(即:放大、缩小或打印拖动)之类的问题,在这些操作中,斑马形记号会丢失其在轴中的位置 如果可能,我希望确保每

我正在尝试为cartopy matplotlib绘图实现斑马样式

这是用于生成地理地图的常用打印样式。一些地理信息系统已经实现了这种方式。然而,Python并不拥有它

我已经成功地生成了一个函数,可以在给定的cartopy的GeoAxis中添加斑马状的蜱虫

尽管如此,尽管我努力更新算法,但我无法允许自动更新斑马蜱的坐标。此更新将允许解决诸如event.callbacks.connect操作(即:放大、缩小或打印拖动)之类的问题,在这些操作中,斑马形记号会丢失其在轴中的位置

如果可能,我希望确保每次用户应用某种缩放或拖动操作时,相应的斑马状刻度也会自动更新

我已经尝试为matplotlib的callbacks.connect方法实现类的概念,如和所述

以下是迄今为止的脚本:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature

import matplotlib.patches as mpatches
from matplotlib.offsetbox import AnchoredText

from cartopy.mpl.geoaxes import GeoAxesSubplot

class zebra_ticks():

    def __init__(self, ax=None, 
             projection = ccrs.PlateCarree(), 
             drawlicense=True,
             pad=2):

        if not isinstance(ax, GeoAxesSubplot):

            self.fig = plt.figure(figsize=(9,7))
            self.ax = plt.axes(projection=projection)


            # Put a background image on for nice sea rendering.
        self.ax.stock_img()

        # Create a feature for States/Admin 1 regions at 1:50m from Natural Earth
        states_provinces = cfeature.NaturalEarthFeature(
            category='cultural',
            name='admin_1_states_provinces_lines',
            scale='50m',
            facecolor='none')

        SOURCE = 'Natural Earth'
        LICENSE = 'public domain'

        self.ax.add_feature(cfeature.LAND)
        self.ax.add_feature(cfeature.COASTLINE)
        self.ax.add_feature(states_provinces, edgecolor='gray')

        # Add a text annotation for the license information to the
        # the bottom right corner.

        if drawlicense:

            text = AnchoredText(r'$\mathcircled{{c}}$ {}; license: {}'
                                ''.format(SOURCE, LICENSE),
                                loc='right',
                                bbox_transform=self.ax.transAxes,
                                bbox_to_anchor=(1.01, -0.11), 
                                prop={'size': 8}, 
                                frameon=False)

            self.ax.add_artist(text)

        self.gridliner = self.ax.gridlines(draw_labels=True)
        self.pad = pad
        self.zebras = self.add_zebra()


        plt.show()

        self.ax.callbacks.connect('xlim_changed', lambda x: self.update_zebra)
        self.ax.callbacks.connect('ylim_changed', lambda x: self.update_zebra)



    def add_zebra(self):
        '''
        Description:

            This function add a zebra line border around a cartopy's geoaxes.

            It uses the coordinates tick position to evaluate the zebra blocks.


        returns (dict): {'horizontal:'horizontal_zebras, 'vertical':vertical_zebras}

        '''


        self.fig.canvas.draw()   

        lon0, lon1, lat0, lat1 = self.ax.get_extent(crs=self.ax.projection)

        ysegs = self.gridliner.yline_artists[0].get_segments()
        yticks = [yseg[0,1] for yseg in ysegs]

        xsegs = self.gridliner.xline_artists[0].get_segments()
        xticks = [xseg[0,0] for xseg in xsegs]
        xticks.append(lon1)

        i = 0

        colors_wk = ['white', 'black']


        horizontal_zebras={'north':[],
                           'south':[]}


        vertical_zebras={'east':[],
                           'west':[]}


        for lon, position in zip([lon0, lon1 - self.pad], ['east', 'west']):
            y0 = xticks[0]
            for enum, y in enumerate(yticks[1:]):

                color = colors_wk[i]

                delta_coor = (y - y0)

                vertical_rect = mpatches.Rectangle( (lon, y0), self.pad , delta_coor, 
                                          transform=self.ax.transData,
                                          facecolor=color, zorder=1000)

                vertical_zebras[position].append(vertical_rect)

                i = 1 - i
                y0 = y

                self.ax.add_patch(vertical_rect)


        for lat, position in zip([lat0, lat1 - self.pad], ['south', 'north']):
            x0 = xticks[0]

            for x in xticks[1:]:

                color = colors_wk[i]

                delta_coor = (x - x0)


                horizontal_rect = mpatches.Rectangle( (x0, lat), delta_coor, self.pad ,
                                          transform=self.ax.transData,
                                          facecolor=color, zorder=1000)


                horizontal_zebras[position].append(horizontal_rect)


                x0 = x

                i = 1 - i

                self.ax.add_patch(horizontal_rect)





        if self.ax.projection.proj4_params.get('units', 'None') == 'None':

            if not (lon0 <=-180 or lon1 >= 180 or lat0>=90 or lat0<=-90):

                self.ax.set_extent((lon0-self.pad, 
                                    lon1+self.pad, 
                                    lat0-self.pad, 
                                    lat1+self.pad))

        return {'horizontal':horizontal_zebras, 
                'vertical':vertical_zebras}


    def update_zebra(self, event):
        axes = event.axes
        # trigger the outline and background patches to be re-clipped
        axes.outline_patch.reclip = True
        axes.background_patch.reclip = True

        lon0, lon1, lat0, lat1 = self.ax.get_extent(crs=self.ax.projection)

        ysegs = self.gridliner.yline_artists[0].get_segments()
        yticks = [yseg[0,1] for yseg in ysegs]

        xsegs = self.gridliner.xline_artists[0].get_segments()
        xticks = [xseg[0,0] for xseg in xsegs]
        xticks.append(lon1)

        for Vzebras in self.zebras['vertical']:
            for zebra in Vzebras:

                for lon, position in zip([lon0, lon1 - self.pad], ['east', 'west']):
                    y0 = xticks[0]
                    for enum, y in enumerate(yticks[1:]):

                        delta_coor = (y - y0)

                        zebra.set_bounds( lon, y0, self.pad , delta_coor)

                        y0 = y


        for Hzebras in self.zebras['vertical']:
            for zebra in Hzebras:

                for lat, position in zip([lat0, lat1 - self.pad], ['south', 'north']):
                    x0 = xticks[0]

                    for x in xticks[1:]:

                        delta_coor = (x - x0)


                        zebra.set_bounds( x0, lat, 
                                         delta_coor, 
                                         self.pad )


                        x0 = y



if '__main__' == __name__:

    Z = zebra_ticks()
导入matplotlib.pyplot作为plt
将cartopy.crs作为CCR导入
将cartopy.feature导入为cfeature
将matplotlib.patches作为MPatch导入
从matplotlib.offsetbox导入锚定文本
从cartopy.mpl.geoaxes导入GeoAxesSubplot
类斑马蜱():
def uuu init uuu(self,ax=None,
投影=ccrs.PlateCarree(),
drawlicense=True,
pad=2):
如果不存在(ax、GeoAxesSubplot):
self.fig=plt.figure(图大小=(9,7))
self.ax=plt.轴(投影=投影)
#将背景图像放在屏幕上,以进行漂亮的海洋渲染。
self.ax.stock_img()
#为距离自然地球1:50米的州/行政区创建要素
州/省=cfeature.NaturalEarthFeature(
“文化”类,
name='admin'u 1'州\省\线',
比例尺='50m',
facecolor='none')
来源=‘自然地球’
许可证='公共域'
self.ax.add_特征(cfeature.LAND)
self.ax.add_特征(C特征.海岸线)
self.ax.add\u功能(州/省,edgecolor='gray')
#将许可证信息的文本批注添加到
#右下角。
如果获得许可证:
text=AnchoredText(r'$\mathcircled{{{c}}}${};许可证:{}'
''格式(来源、许可证),
loc='right',
bbox_transform=self.ax.transAxes,
bbox_至_锚=(1.01,-0.11),
prop={'size':8},
frameon=False)
self.ax.add_艺术家(文本)
self.gridliner=self.ax.gridlines(draw\u labels=True)
self.pad=pad
self.zebras=self.add_zebra()
plt.show()
self.ax.callbacks.connect('xlim\u changed',lambda x:self.update\u zebra)
self.ax.callbacks.connect('ylim\u changed',lambda x:self.update\u zebra)
def添加斑马(自身):
'''
说明:
此函数用于在cartopy的地理轴周围添加斑马线边框。
它使用坐标记号位置来计算斑马块。
返回(dict):{'horizontal:'horizontal_斑马,'vertical':vertical_斑马}
'''
self.fig.canvas.draw()
lon0,lon1,lat0,lat1=self.ax.get_区段(crs=self.ax.projection)
ysegs=self.gridliner.yline\u艺术家[0]。获取分段()
yticks=[yseg[0,1]表示yseg中的yseg]
xsegs=self.gridliner.xline_艺术家[0]。获取_段()
xticks=[xseg[0,0]表示xsegs中的xseg]
xticks.append(lon1)
i=0
颜色_wk=[“白色”、“黑色”]
水平斑马={'north':[],
“南部”:[]}
垂直斑马={'east':[],
“西部”:[]}
对于lon,在拉链中定位([lon0,lon1-self.pad],“东”,“西]):
y0=xticks[0]
对于枚举,枚举中的y(yticks[1:]):
颜色=颜色\u wk[i]
delta_coor=(y-y0)
垂直矩形=匹配矩形((lon,y0),自焊盘,三角形,
转换=self.ax.transData,
facecolor=color,zorder=1000)
垂直斑马[position]。追加(垂直方向)
i=1-i
y0=y
self.ax.add_patch(垂直方向)
对于lat,在zip中定位([lat0,lat1-self.pad],“南”,“北]):
x0=xticks[0]
对于xticks[1:]中的x:
颜色=颜色\u wk[i]
delta_coor=(x-x0)
水平矩形=mpatches.矩形((x0,横向),三角形,自焊盘,
转换=self.ax.transData,
facecolor=color,zorder=1000)
水平斑马[position]。追加(水平方向)
x0=x
i=1-i
self.ax.add_补丁(水平方向)
如果self.ax.projection.proj4_params.get('units','None')=='None':

如果不是(Lo0=180或LAT0>=90或LAT0),你就永远不能调用<代码>自己。UpDeTeY.ZEBRA < /Case>方法。考虑<代码> lambda x:NoPy.Sin < /C> >,它不计算任何东西的正弦。亲爱的ImportanceOfBeingErnest,我应该怎样在哪里做?你能发布更详细的答案吗?