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

Python绘制多轴刻度雷达图的问题(Matplotlib实现)

多刻度雷达图刻度匹配问题修复

原本计划用VEDO生成复杂雷达图,后来参考Stack Overflow上的Matplotlib示例代码修改,目标实现各坐标轴带独立多刻度的雷达图,但运行后发现所有线条都只适配第一轴的刻度规则,无法对应各自轴的正确刻度位置。

原代码

import numpy as np
import pylab as pl
from matplotlib import pyplot as plt

class Radar(object):

    def __init__(self, fig, titles, labels, rect=None):
        if rect is None:
            rect = [0.05, 0.05, 0.95, 0.95]

        self.n = len(titles)
        self.angles = np.arange(90, 90+360, 360.0/self.n)
        self.angles = [a % 360 for a in self.angles]
        self.axes = [fig.add_axes(rect, projection="polar", label="axes%d" % i)
                         for i in range(self.n)]

        self.ax = self.axes[0]
        self.ax.set_thetagrids(self.angles, labels=titles, fontsize=14)

        for ax in self.axes[0:]:
            ax.patch.set_visible(False)
            ax.grid("off")
            ax.xaxis.set_visible(False)

        index = 0
        for ax, angle, label in zip(self.axes, self.angles, labels):
            ax.set_rgrids(range(1, label.__len__()+1), angle=angle, labels=label)
            ax.spines["polar"].set_visible(True)
            ax.set_ylim(0, label.__len__())
            index+=1


    def plot(self, values, *args, **kw):
        angle = np.deg2rad(np.r_[self.angles, self.angles[0]])
        values = np.r_[values, values[0]]
        self.ax.plot(angle, values, *args, **kw)



fig = pl.figure(figsize=(6, 6))

titles = list("ABCDE")

labels = [
    list("abc"), list("12345"), list("uvwxy"),
    ["one", "two", "three", "four", "five"],
    list("jklmn")
]

radar = Radar(fig, titles, labels)
radar.plot([2,2,2,2,2],  "-", lw=2, color="b", alpha=0.4, label="first")
radar.plot([2.3, 2, 3, 3, 2],"-", lw=2, color="r", alpha=0.4, label="second")
radar.plot([3, 4, 3, 4, 2], "-", lw=2, color="g", alpha=0.4, label="third")
radar.ax.legend()

plt.show()

问题根源

原代码存在两个核心问题:

  • 所有绘图操作都在第一个轴(self.ax = self.axes[0])上执行,而每个轴的ylim范围不同(比如第一轴是0-3,第二轴是0-5),导致其他轴的数值无法匹配自身刻度。
  • 直接使用原始数值绘图,没有考虑不同轴的刻度数量差异,数值对应的径向位置在不同轴上不匹配。

修复后的代码

import numpy as np
import pylab as pl
from matplotlib import pyplot as plt

class Radar(object):

    def __init__(self, fig, titles, labels, rect=None):
        if rect is None:
            rect = [0.05, 0.05, 0.95, 0.95]

        self.n = len(titles)
        self.angles = np.arange(90, 90+360, 360.0/self.n)
        self.angles = [a % 360 for a in self.angles]
        # 保存每个轴的刻度数量,用于后续归一化
        self.label_lengths = [len(lbl) for lbl in labels]
        self.axes = [fig.add_axes(rect, projection="polar", label="axes%d" % i)
                         for i in range(self.n)]

        self.ax = self.axes[0]
        self.ax.set_thetagrids(self.angles, labels=titles, fontsize=14)

        for ax in self.axes:
            ax.patch.set_visible(False)
            ax.grid("off")
            ax.xaxis.set_visible(False)

        for ax, angle, label, length in zip(self.axes, self.angles, labels, self.label_lengths):
            # 计算归一化后的刻度位置(0-1范围)
            grid_positions = [i/length for i in range(1, length+1)]
            ax.set_rgrids(grid_positions, angle=angle, labels=label)
            ax.spines["polar"].set_visible(True)
            ax.set_ylim(0, 1)  # 统一所有轴的径向范围为0-1


    def plot(self, values, *args, **kw):
        # 将每个数值归一化到对应轴的0-1范围
        normalized_values = [val/self.label_lengths[i] for i, val in enumerate(values)]
        angle = np.deg2rad(np.r_[self.angles, self.angles[0]])
        normalized_values = np.r_[normalized_values, normalized_values[0]]
        self.ax.plot(angle, normalized_values, *args, **kw)



fig = pl.figure(figsize=(6, 6))

titles = list("ABCDE")

labels = [
    list("abc"), list("12345"), list("uvwxy"),
    ["one", "two", "three", "four", "five"],
    list("jklmn")
]

radar = Radar(fig, titles, labels)
# 传入的数值对应各轴的刻度索引(从1开始)
radar.plot([2,2,2,2,2],  "-", lw=2, color="b", alpha=0.4, label="first")
radar.plot([2, 2, 3, 3, 2],"-", lw=2, color="r", alpha=0.4, label="second")
radar.plot([3, 4, 3, 4, 2], "-", lw=2, color="g", alpha=0.4, label="third")
radar.ax.legend()

plt.show()

修复说明

  1. 统一径向范围:将所有轴的ylim设置为0-1,避免不同轴的刻度范围冲突。
  2. 数值归一化:在绘图前,把每个轴的原始数值(对应刻度的索引)转换为相对于该轴刻度数量的比例,确保数值能匹配对应轴的刻度位置。
  3. 刻度位置调整:每个轴的径向刻度位置也按比例计算,保证刻度显示在正确的归一化位置上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 14:24:16