You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Geopandas高亮国家时地图尺寸变化的解决方法

解决Geopandas+Matplotlib绘制地图时高亮国家导致尺寸变化的问题

问题场景

使用Geopandas结合Matplotlib、wxPython绘制世界地图,每次左键点击随机高亮某个国家时,地图的显示范围会发生变化,无法保持初始的世界地图视图。

问题原因

调用Geopandas的plot()方法绘制单个国家时,Matplotlib会自动调整坐标轴的x、y范围,使其适配当前绘制的要素边界,导致原本的世界地图范围被覆盖,出现视图缩放的问题。

解决方案

在绘制高亮国家之前,先获取原始世界地图的坐标轴范围(xlim和ylim),绘制完成后强制将坐标轴范围重置为原始值,固定地图的显示范围。同时可以提前转换世界地图的CRS,避免重复计算提升性能。

修改后的完整代码

import wx
import matplotlib
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
import geopandas as gpd
import random
import pathlib
import os

# 修正路径获取错误:去掉print,否则this_directory会返回None
this_directory = pathlib.Path(__file__).parent.resolve()
WORLDX = os.path.join(this_directory, "ne_110m_admin_0_countries.shp") 
WATER = '#defafc'
LAND = '#807e7e'
LEFT_MOUSE = matplotlib.backend_bases.MouseButton.LEFT


class MapFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Map",
                          style=wx.DEFAULT_FRAME_STYLE,
                          size=wx.Size(1200, 900))
        self.main_panel = MapPanel(self)
        self.Bind(wx.EVT_CLOSE, self.OnClose)

    def OnClose(self, _event):
        self.Destroy()
        wx.Exit()

class MapPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.SetDoubleBuffered(True)

        self.figure = Figure()
        self.result_frame = parent
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.axes = self.figure.add_axes([0, 0, 1, 1])
        self.axes.margins(0.0)
        self.axes.set_anchor('C')

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()
        self.Layout()
        self.countries = ["US", "FR", "GB", "BR", "IN", "AU", "NZ", "IT", "DE"]
        # 提前转换CRS,避免每次绘制重复计算
        self.world_data = gpd.read_file(WORLDX).to_crs(epsg=4326)
        self.map_plot = None
        self.drawMap()

    def drawMap(self, country_highlight=None):
        """Draw the map on the canvas. """
        self.axes.clear()
        self.axes.axis('off')
        self.figure.set_facecolor(WATER)
        # 绘制完整世界地图
        self.map_plot = self.world_data.plot(ax=self.axes, color=LAND)
        
        if country_highlight:
            # 先获取原始世界地图的坐标轴范围
            original_xlim = self.map_plot.get_xlim()
            original_ylim = self.map_plot.get_ylim()
            # 绘制高亮国家
            self.world_data[self.world_data.ISO_A2_EH == country_highlight].plot(
                edgecolor=u'gray', color='#fa8a48', ax=self.map_plot
            )
            # 强制重置坐标轴范围为原始值,固定视图
            self.map_plot.set_xlim(original_xlim)
            self.map_plot.set_ylim(original_ylim)

        self.canvas.draw()

    def onLeftClick(self, event):
        if event.button == LEFT_MOUSE:
            self.drawMap(random.choice(self.countries))


class MyApp(wx.App):
    def OnInit(self):
        frame = MapFrame()
        frame.Show()
        return True

if __name__ == "__main__":
    app = MyApp()
    app.MainLoop()

关键修改点

  • 提前转换世界地图的CRS到epsg=4326,避免每次调用drawMap时重复执行to_crs,提升绘制效率。
  • 在绘制高亮国家前获取原始世界地图的xlim和ylim,绘制完成后立即重置坐标轴范围,强制固定地图视图。
  • 修正了原代码中this_directory获取的错误(去掉多余的print,否则会导致路径拼接失败)。

内容的提问来源于stack exchange,提问作者Steve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 17:01:26