无需QML,在PySide6中实现国家级别choropleth map的最简方案
在PySide6中实现国家级别Choropleth地图的最简方法
方案1:Matplotlib + GeoPandas 嵌入PySide6窗口
这是最省心的方案,借助成熟的地理绘图库生成地图,再嵌入PySide6界面,无需从零实现地理数据渲染。
步骤:
- 安装依赖:
pip install geopandas matplotlib pyside6
- 加载世界国家地理数据,关联自定义数值数据
- 绘制Choropleth地图,将Matplotlib画布嵌入PySide6窗口
示例代码:
import sys import geopandas as gpd import matplotlib.pyplot as plt from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout class MapWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("国家Choropleth地图") self.setGeometry(100, 100, 800, 600) # 加载世界国家地理数据 world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres')) # 模拟自定义数值数据(键为国家名称,值为对应数值) country_values = { "China": 90, "United States": 85, "India": 70, "Brazil": 65, "Russia": 75 } # 关联地理数据和数值(处理名称匹配差异) world['value'] = world['name'].map(country_values).fillna(0) # 创建Matplotlib画布 self.figure, self.ax = plt.subplots(figsize=(8, 6)) self.canvas = FigureCanvas(self.figure) # 绘制Choropleth地图 world.plot(column='value', cmap='YlOrRd', linewidth=0.8, ax=self.ax, edgecolor='0.8', legend=True) self.ax.set_axis_off() # 将画布嵌入PySide6窗口 central_widget = QWidget() layout = QVBoxLayout(central_widget) layout.addWidget(self.canvas) self.setCentralWidget(central_widget) if __name__ == "__main__": app = QApplication(sys.argv) window = MapWindow() window.show() sys.exit(app.exec())
注意事项:
- 国家名称可能存在差异(比如GeoPandas里的"United States" vs 自定义数据里的"USA"),需要手动制作名称映射表
- 可通过调整
cmap参数更换配色方案,比如viridis、Blues等
方案2:基于SVG地图的原生PySide6实现
如果不想依赖Matplotlib,可使用原生PySide6图形框架处理SVG地图,直接给对应国家元素上色。
步骤:
- 下载包含国家独立元素的SVG世界地图(确保每个国家路径有唯一标识,比如
id或data-name属性) - 加载SVG到
QGraphicsScene - 遍历SVG元素,匹配自定义数值数据,设置填充颜色
- 将
QGraphicsView嵌入PySide6窗口
示例代码:
import sys from PySide6.QtWidgets import QApplication, QMainWindow, QGraphicsView, QGraphicsScene from PySide6.QtSvg import QSvgRenderer from PySide6.QtGui import QBrush, QColor from PySide6.QtCore import QRectF class SVGMapWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("SVG国家Choropleth地图") self.setGeometry(100, 100, 800, 600) # 加载SVG地图文件(替换为你的SVG路径) svg_renderer = QSvgRenderer("world_map.svg") scene = QGraphicsScene() view = QGraphicsView(scene) view.setRenderHint(QSvgRenderer.Antialiasing) # 模拟自定义数值数据 country_values = { "China": 90, "United States": 85, "India": 70 } # 定义颜色映射(数值0-100对应从浅到深的红色) def get_color(value): if value == 0: return QColor(240, 240, 240) intensity = int(255 - (value / 100) * 150) return QColor(255, intensity, intensity) # 遍历SVG元素,匹配国家并上色 for element_id in svg_renderer.elements(): country_name = element_id # 假设SVG元素的id是国家名称,需根据实际SVG调整 value = country_values.get(country_name, 0) brush = QBrush(get_color(value)) # 获取元素路径并添加到场景 path = svg_renderer.elementPath(element_id) if not path.isEmpty(): item = scene.addPath(path) item.setBrush(brush) # 设置视图范围 scene.setSceneRect(QRectF(svg_renderer.viewBox())) self.setCentralWidget(view) if __name__ == "__main__": app = QApplication(sys.argv) window = SVGMapWindow() window.show() sys.exit(app.exec())
注意事项:
- 需要确保SVG地图的每个国家元素有可识别的标识(比如
id或自定义属性),否则无法匹配数值 - 颜色映射逻辑可根据需求自定义,比如使用渐变色或预设色阶
内容的提问来源于stack exchange,提问作者David Frick
相关产品推荐
相关产品推荐

