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

基于Matplotlib的抛物线路径连接图:曲率参数增强需求

实现带抛物弧线的英国多点汇聚连接图

问题根源

你的代码当前绘制直线的核心原因是三个拟合点共线:你取了起点、终点的中点作为第二个点,这三个点在同一条直线上,导致拟合出的二次函数系数a=0,退化成一次直线,自然没有曲率。

解决方案

给中间点添加垂直于两点连线的偏移量,让它脱离直线,这样拟合的抛物线就会产生明显弧度。我们新增一个curvature参数控制偏移大小,适配英国区域的EPSG:3857坐标系(单位为米,偏移量设为几万米比较合适)。

修改后的完整代码

import numpy as np
import matplotlib.pyplot as plt
import contextily as ctx
import sympy as sm

def plot_connection(ax, start_point, end_point, curvature=50000):
    x1, y1 = start_point[0], start_point[1]
    x3, y3 = end_point[0], end_point[1]
    
    # 计算两点中点
    x_mid = (x1 + x3) / 2
    y_mid = (y1 + y3) / 2
    
    # 计算连线的垂直方向向量,保证弧线统一向上弯曲
    dx = x3 - x1
    dy = y3 - y1
    perp_dx = -dy
    perp_dy = dx
    # 归一化垂直向量
    vec_length = np.sqrt(perp_dx**2 + perp_dy**2)
    perp_dx /= vec_length
    perp_dy /= vec_length
    
    # 偏移中间点,生成带曲率的拟合点
    x2 = x_mid + perp_dx * curvature
    y2 = y_mid + perp_dy * curvature
    
    x = np.array([x1, x2, x3])
    y = np.array([y1, y2, y3])

    a, b, c = sm.symbols('a b c', real=True)
    
    eq1 = sm.Eq((x[0]**2) * a + x[0] * b + c, y[0])
    eq2 = sm.Eq((x[1]**2) * a + x[1] * b + c, y[1])
    eq3 = sm.Eq((x[2]**2) * a + x[2] * b + c, y[2])

    sol = sm.solve([eq1, eq2, eq3], (a, b, c))

    def f(x_val):
        return sol[a] * (x_val**2) + sol[b] * x_val + sol[c]

    # 用plot替代scatter,绘制更流畅的弧线,提升渲染效率
    x_vals = np.linspace(x[0], x[-1], 1500)
    y_vals = f(x_vals)
    ax.plot(x_vals, y_vals, color='gray', alpha=0.6, zorder=-3)

# 目标点与各城市坐标(EPSG:3857坐标系)
target = (-251467.639557, 7014473.211674)
london = (-23236.856599, 6713617.068344)
glasgow = (-472686.582916, 7534245.004013)
leeds = (-173664.928264, 7133714.975799)
brighton = (-14675.909431, 6599267.274029)
darmstadt = (88791.533909, 6672007.566294)
manchester = (-251095.637917, 7069851.838667)

fig, ax = plt.subplots(figsize=(15, 15))

# 绘制各连接弧线,可针对不同城市调整curvature值优化视觉效果
plot_connection(ax, target, london, curvature=60000)
plot_connection(ax, target, glasgow, curvature=60000)
plot_connection(ax, target, leeds, curvature=40000)
plot_connection(ax, target, brighton, curvature=60000)
plot_connection(ax, target, darmstadt, curvature=60000)
plot_connection(ax, target, manchester, curvature=20000)

# 聚焦英国区域范围
ax.set_xlim(-520000, 175000)
ax.set_ylim(6500000, 8200000)

ctx.add_basemap(ax, source=ctx.providers.CartoDB.PositronNoLabels, zorder=-4, crs='EPSG:3857')
ax.axis('off')
plt.tight_layout()
plt.show()

关键修改说明

  • 新增curvature参数:控制中间点的偏移距离,值越大弧线曲率越明显,可针对不同城市单独调整,让视觉效果更协调。
  • 统一偏移方向:通过计算连线的垂直向量,保证所有弧线向上弯曲,避免杂乱的方向差异。
  • 替换渲染方式:用ax.plot替代plt.scatter,绘制连续线条更流畅,同时提升代码运行效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:30:31