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

向Mapbox添加图层时出现新问题:Plotly渲染异常

Plotly Mapbox图层叠加异常问题
  • 运行2年多的代码突然生成异常Plotly绘图,经测试确认问题出在Plotly/plotly.js端,与运行环境无关
  • 当前使用Plotly 5.17版本,升级至最新版后问题仍存在(对应plotly.js版本为2.30.0)
  • 代码功能:将经纬度数据及对应值生成MultiPolygons格式的轮廓图层,并叠加到Mapbox上

复现资源

复现所需数据可从指定代码仓库获取

复现代码

import pandas as pd
from datetime import datetime, date
import plotly.express as px
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata,RectSphereBivariateSpline,Rbf
import geojsoncontour
import json
import branca
import scipy as sp
import scipy.ndimage
from geojson import Feature, Polygon, dump
import geopandas as gpd
from urllib.request import urlopen
import shapely.geometry
from shapely.geometry import Point, Polygon, GeometryCollection, Polygon, mapping
from shapely.ops import unary_union
from shapely.validation import make_valid
import math

# Contours
con = [-10, -5, -2.5, -1, 0, 1, 2.5, 5, 15]

colors = ['#e6572b','#f28f38','#f2b138','#f2d338','#7eae79','#0a88ba','#0b5e9f','#0c3383','#6600FF']

data = []

df = pd.read_csv('path/to/csv/from/GitHib/data.csv')

df_cont = df.dropna().copy()

levels = con
unit = ''


vmin   = 0
vmax   = 1
cm     = branca.colormap.LinearColormap(colors, vmin=vmin, vmax=vmax).to_step(len(levels))


x_orig = (df_cont['Long'].values.tolist())
y_orig = (df_cont['Lat'].values.tolist())
z_orig = np.asarray(df_cont[month].values.tolist())


x_arr          = np.linspace(np.min(x_orig), np.max(x_orig), 1000)
y_arr          = np.linspace(np.min(y_orig), np.max(y_orig), 1000)
x_mesh, y_mesh = np.meshgrid(x_arr, y_arr)


xscale = df_cont['Long'].max() - df_cont['Long'].min()
yscale = df_cont['Lat'].max() - df_cont['Lat'].min()

scale = np.array([xscale, yscale])


z_mesh = griddata((x_orig, y_orig), z_orig, (x_mesh, y_mesh), method='linear')


sigma = [5, 5]
z_mesh = sp.ndimage.filters.gaussian_filter(z_mesh, sigma, mode='nearest')

# Create the contour
contourf = plt.contourf(x_mesh, y_mesh, z_mesh, levels, alpha=0.9, colors=colors, 
                        linestyles='none', vmin=vmin, vmax=vmax)

# Convert matplotlib contourf to geojson
geojson = geojsoncontour.contourf_to_geojson(
    contourf=contourf,
    min_angle_deg=3,
    ndigits=2,
    unit=unit,
    stroke_width=1,
    fill_opacity=0.3)

d = json.loads(geojson)
len_features=len(d['features'])
if not data:
    data.append(d)
else:
    for i in range(len(d['features'])):
         data[0]['features'].append(d['features'][i])
            
with open('path/to/any/directory/to/hold/created_geojson/temp_conditions_contour.geojson', 'w') as f:
    dump(geojson, f)

# reading in the geospatial data for the state and province boundaries
with open('path/to/the/data/from/GitHub/states_and_provinces.geojson') as f:
    states_and_provinces_json = json.load(f)

conditions_json = json.loads(geojson)

fig = px.density_mapbox(
                        df_cont,
                        lat='Lat',
                        lon='Long',
                        z=month,
                        hover_data={
                            'Code':True,
                            'Lat': True,  # remove from hover data
                            'Long': True,  # remove from hover data
                            month: True,
                        },

                        center=dict(lat=38, lon=-95), # L48 + Lower CAN
                        zoom=2.75, # L48 + Lower CAN
                        
#                         center=dict(lat=38, lon=-112), # NAM
#                         zoom=2.1, # NAM
                        
                        opacity = 0.4,
                        radius = 15,
                        mapbox_style='white-bg',
                        color_continuous_scale=['rgb(0,0,0)',
                                                'rgb(19,48,239)',
                                                'rgb(115,249,253)',
                                                'rgb(114,245,77)',
                                                'rgb(254,251,84)',
                                                'rgb(235,70,38)'],
                        range_color = [100000000, 1000000000]
                    )


# Conditions outlines
fig.update_layout(
    mapbox={
        'layers': [
            {
                'source': f,
                'line': {'width':5},
                'type':'line',
                'type':'fill',
                'color': f['properties']['fill'],
                'opacity': 1,
            }
            for f in conditions_json['features']
        ],
    }
)

# States outlines
fig.update_layout(
    mapbox={
        "layers": [
            {
                'source': g,
                'line': {"width":0.5},
                'type':"line",
                'color': 'black',
                'opacity': 1,
            }
            for g in states_and_provinces_json["features"]
        ],
    }
)

# Update the hover info and legend -- legend was replaced with image of legend
fig.update_layout(xaxis=dict(fixedrange=True),
                  yaxis=dict(fixedrange=True),

                  coloraxis_showscale=False,
)

# Update size
fig.update_layout(
    autosize=False,
    width=900,
    height=900)

fig.show()

环境信息

  • Python版本:3.11
  • Plotly版本信息:
Name: plotly
Version: 5.17.0
Summary: An open-source, interactive data visualization library for Python
Home-page: https://plotly.com/python/
Author: Chris P
Author-email: chris@plot.ly
License: MIT
Location: /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages
Requires: packaging, tenacity
Required-by: dash

效果对比

正常轮廓效果

正常轮廓效果

异常渲染效果1

异常渲染效果1

异常渲染效果2

异常渲染效果2

异常渲染效果3

异常渲染效果3

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 22:25:54