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

如何为Polarchart的线条/数据点设置圆角?参考d3包实现方式

Polarchart 线条与数据点圆角实现方案

一、线条设置圆角

1. Matplotlib 实现

Matplotlib 默认极坐标线条无圆角,可通过自定义路径生成带圆角的折线:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.path import Path
from matplotlib.patches import PathPatch

# 生成测试数据
theta = np.linspace(0, 2*np.pi, 6)
r = np.array([1, 2, 1.5, 2.5, 1.8, 1])
x = r * np.cos(theta)
y = r * np.sin(theta)

# 生成带圆角的路径
def rounded_path(x, y, radius=0.1):
    vertices = []
    codes = []
    n = len(x)
    for i in range(n):
        curr = (x[i], y[i])
        next_idx = (i+1) % n
        next_pt = (x[next_idx], y[next_idx])
        prev_idx = (i-1) % n
        prev_pt = (x[prev_idx], y[prev_idx])
        
        # 计算切线方向,生成圆角控制点
        dx1, dy1 = curr[0]-prev_pt[0], curr[1]-prev_pt[1]
        len1 = np.hypot(dx1, dy1)
        dx1, dy1 = (dx1/len1, dy1/len1) if len1 > 0 else (0,0)
        
        dx2, dy2 = next_pt[0]-curr[0], next_pt[1]-curr[1]
        len2 = np.hypot(dx2, dy2)
        dx2, dy2 = (dx2/len2, dy2/len2) if len2 > 0 else (0,0)
        
        start = (curr[0]-dx1*radius, curr[1]-dy1*radius)
        end = (curr[0]+dx2*radius, curr[1]+dy2*radius)
        
        vertices.extend([start, curr, end])
        codes.extend([Path.LINETO, Path.CURVE3, Path.LINETO])
    
    vertices.append(vertices[0])
    codes.append(Path.CLOSEPOLY)
    return Path(vertices, codes)

fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
path = rounded_path(x, y, radius=0.05)
patch = PathPatch(path, facecolor='none', edgecolor='blue', linewidth=2)
ax.add_patch(patch)
ax.set_ylim(0, 3)
plt.show()

2. Chart.js 实现

通过自定义插件修改线条渲染样式,利用 Canvas 的 lineJoin='round' 属性:

Chart.plugins.register({
  beforeDraw: function(chart) {
    if (chart.config.type === 'radar') {
      chart.data.datasets.forEach(dataset => {
        dataset._meta.forEach(meta => {
          meta.dataset._model.borderJoinStyle = 'round';
        });
      });
    }
  }
});

// 初始化雷达图
new Chart(document.getElementById('myChart'), {
  type: 'radar',
  data: {
    labels: ['A','B','C','D','E','F'],
    datasets: [{data: [1,2,1.5,2.5,1.8,1], borderColor: 'blue'}]
  },
  options: {elements: {line: {borderWidth: 2}}}
});

二、数据点设置圆角

1. Matplotlib 实现

可使用内置圆形标记,或自定义圆角标记:

from matplotlib.markers import MarkerStyle

# 自定义圆角矩形标记
def rounded_rect_marker(radius=0.1):
    path = Path([(-0.5,-0.5), (-0.5,0.5), (0.5,0.5), (0.5,-0.5), (-0.5,-0.5)],
                [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY])
    path = path.transformed(MarkerStyle.get_transform_for_path(path, 'round', radius))
    return MarkerStyle(path)

# 在极坐标图中使用
ax.scatter(theta, r, marker=rounded_rect_marker(0.05), s=100, color='red')

2. Chart.js 实现

直接使用内置的圆角矩形标记,或圆形标记:

options: {
  elements: {
    point: {
      pointStyle: 'rectRounded', // 内置圆角矩形
      radius: 6,
      borderWidth: 2,
      backgroundColor: 'red'
    }
  }
}

三、替代方案

如果现有库支持不足,直接使用 D3.js 是最灵活的选择:

const svg = d3.select("svg")
  .attr("width", 400)
  .attr("height", 400)
  .append("g")
  .attr("transform", "translate(200,200)");

// 极坐标比例尺
const rScale = d3.scaleLinear().domain([0,3]).range([0,150]);
const thetaScale = d3.scaleLinear().domain([0,2*Math.PI]).range([0,2*Math.PI]);

// 圆角线条生成器
const line = d3.lineRadial()
  .angle(d => thetaScale(d.theta))
  .radius(d => rScale(d.r))
  .curve(d3.curveNatural); // 自然曲线实现圆角

// 测试数据
const data = [
  {theta:0,r:1}, {theta:Math.PI/3,r:2}, {theta:2*Math.PI/3,r:1.5},
  {theta:Math.PI,r:2.5}, {theta:4*Math.PI/3,r:1.8}, {theta:5*Math.PI/3,r:1}
];

// 绘制线条
svg.append("path")
  .datum(data)
  .attr("d", line)
  .attr("fill", "none")
  .attr("stroke", "blue")
  .attr("stroke-width", 2);

// 绘制圆角数据点
svg.selectAll("circle")
  .data(data)
  .enter()
  .append("circle")
  .attr("cx", d => rScale(d.r)*Math.cos(thetaScale(d.theta)))
  .attr("cy", d => rScale(d.r)*Math.sin(thetaScale(d.theta)))
  .attr("r", 6)
  .attr("fill", "red");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 07:26:19