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

基于Panel与hvplot的Xarray地理空间数据交互式可视化开发问题

基于Panel与Xarray复刻地理空间交互式可视化应用

核心需求

  • 将data_vars选择器集成至Panel Material模板
  • 根据所选变量的维度(如ES维度为(time, pres1, lat, lon),P0维度为(time, lat, lon))自动生成对应交互控件,放置在侧边栏(sidebar)
  • 主区域(main)展示带有大陆轮廓的交互式地理空间地图
  • 支持本地fstd格式文件选择与Xarray数据集加载

完整实现代码

import panel as pn
import numpy as np
import hvplot.xarray
import xarray as xr
import fstd2nc
from pathlib import Path

# 初始化Panel扩展
pn.extension(sizing_mode='stretch_width')

# 创建Material模板
template = pn.template.MaterialTemplate(title='地理空间数据可视化',)

# 本地文件路径配置
glob_path = Path(r"C:\Users\spart\Documents\Anaconda-Work-Dir")
file_list = [str(pp).split('\\')[-1] for pp in glob_path.glob("2022*")]

# 定义核心控件
file_sel = pn.widgets.Select(name='选择文件', options=file_list)
var_sel = pn.widgets.Select(name='选择变量', options=[], disabled=True)

# 缓存加载的数据集,避免重复读取
cached_xds = None

@pn.depends(file_sel, watch=True)
def update_variable_list(file_name):
    """选择文件后更新可选择的变量列表"""
    global cached_xds
    file_path = glob_path / file_name
    cached_xds = fstd2nc.Buffer(str(file_path)).to_xarray()
    var_sel.options = list(cached_xds.data_vars)
    var_sel.disabled = False

@pn.depends(var_sel, watch=True)
def update_dimension_controls(var_name):
    """根据选中变量的维度动态生成交互控件"""
    if not cached_xds or not var_name:
        return
    
    # 清空侧边栏中除基础控件外的内容
    template.sidebar[:] = [file_sel, var_sel]
    
    var = cached_xds[var_name]
    # 遍历变量维度生成对应控件
    for dim in var.dims:
        if dim == 'time':
            # 时间维度用下拉选择器
            time_vals = var[dim].values.astype(str)
            time_sel = pn.widgets.Select(name='时间', options=time_vals)
            template.sidebar.append(time_sel)
        elif dim == 'pres1':
            # 气压层维度用滑块
            pres_vals = var[dim].values
            pres_slider = pn.widgets.FloatSlider(
                name='气压层', 
                start=pres_vals.min(), 
                end=pres_vals.max(),
                step=np.diff(pres_vals).min() if len(pres_vals)>1 else 1,
                value=pres_vals[0]
            )
            template.sidebar.append(pres_slider)
    # 其他维度可根据需求扩展

@pn.depends(file_sel, var_sel, time=pn.depends('time_sel'), pres1=pn.depends('pres1_slider'))
def render_plot(file_name, var_name, time=None, pres1=None):
    """根据选择的参数生成带大陆轮廓的可视化图"""
    if not cached_xds or not var_name:
        return pn.pane.Markdown('请选择文件和变量')
    
    var_data = cached_xds[var_name]
    # 根据选择的维度筛选数据
    kwargs = {}
    if time:
        kwargs['time'] = time
    if pres1 is not None:
        kwargs['pres1'] = pres1
    
    if kwargs:
        var_data = var_data.sel(**kwargs)
    
    # 生成图像并叠加大陆轮廓
    plot = var_data.hvplot.image(
        x='lon', y='lat', 
        cmap='jet', height=650, width=1000, data_aspect=1,
        title=f'{var_name} 可视化'
    ).coastline()
    
    return plot

# 初始化侧边栏
template.sidebar.append(file_sel)
template.sidebar.append(var_sel)

# 主区域添加可视化卡片
template.main.append(
    pn.Row(
        pn.Card(render_plot, title='地理空间地图', sizing_mode='stretch_both')
    )
)

# 启动应用
template.show()

关键实现细节

  1. 数据集缓存:使用全局变量cached_xds缓存加载的Xarray Dataset,避免每次交互重复读取文件,提升性能。
  2. 动态控件生成:
    • 选择文件后自动更新变量选择器的选项
    • 选择变量后,根据变量维度(如time、pres1)动态创建对应交互控件,并更新侧边栏内容
  3. 维度筛选与可视化:
    • 根据用户选择的维度参数筛选数据集
    • 用hvplot.image()绘制地理空间图像,通过.coastline()叠加大陆轮廓增强地图可读性
  4. 模板布局:采用Material模板,将控件集中在侧边栏,可视化结果放在主区域卡片中,保持界面结构清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 11:18:19