多轴多尺度雷达图

问题描述 投票:0回答:2

我想使用

matplotlib
绘制在多个轴上具有多个比例的雷达图。 官方API示例仅给出一个轴上的一个刻度。 (本例中的比例为 0.2、0.4、0.6、0.8)

我想要所有轴上都有不同的比例。 (给定示例中有 9 个轴。)

我在这里找到了我正在寻找的示例。这个例子有 5 个轴,所有轴上都有 5 个刻度,就像我想要的那样。

python matplotlib plot
2个回答
19
投票

我认为你可以用多个轴来绘制它,线条位于第一个轴中,其他轴仅显示刻度标签。

import numpy as np
import pylab as pl

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.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[1:]:
            ax.patch.set_visible(False)
            ax.grid("off")
            ax.xaxis.set_visible(False)

        for ax, angle, label in zip(self.axes, self.angles, labels):
            ax.set_rgrids(range(1, 6), angle=angle, labels=label)
            ax.spines["polar"].set_visible(False)
            ax.set_ylim(0, 5)

    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("abcde"), list("12345"), list("uvwxy"), 
    ["one", "two", "three", "four", "five"],
    list("jklmn")
]

radar = Radar(fig, titles, labels)
radar.plot([1, 3, 2, 5, 4],  "-", 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()

enter image description here


0
投票

它接受一个整数/浮点数数据帧和一个 id 列并动态生成雷达图。无论每列的范围如何,都可以工作,因为所有值都在内部缩放到 [0,1] 之间(技术上是 0 和 1/1.25,因为我想提供一些填充),并且只需在右侧打印实际值的文本位置。

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

def spider(df, *, id_column, title=None, max_values=None, padding=1.25):
    categories = df.dtypes[(df.dtypes == 'float') | (df.dtypes == 'int')].index.tolist()
    data = df[categories].to_dict(orient='list')
    ids = df[id_column].tolist()
    if max_values is None:
        max_values = {key: padding*max(value) for key, value in data.items()}
        
    normalized_data = {key: np.array(value) / max_values[key] for key, value in data.items()}
    num_vars = len(data.keys())
    tiks = list(data.keys())
    tiks += tiks[:1]
    angles = np.linspace(0, 2 * np.pi, num_vars, endpoint=False).tolist() + [0]
    fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(polar=True))
    for i, model_name in enumerate(ids):
        values = [normalized_data[key][i] for key in data.keys()]
        actual_values = [data[key][i] for key in data.keys()]
        values += values[:1]  # Close the plot for a better look
        ax.plot(angles, values, label=model_name)
        ax.fill(angles, values, alpha=0.15)
        for _x, _y, t in zip(angles, values, actual_values):
            t = f'{t:.2f}' if isinstance(t, float) else str(t)
            ax.text(_x, _y, t, size='xx-small')
            
    # ax.fill(angles, np.ones(num_vars + 1), alpha=0.25)
    ax.set_yticklabels([])
    ax.set_xticks(angles)
    ax.set_xticklabels(tiks)
    ax.legend(loc='upper right', bbox_to_anchor=(0.1, 0.1))
    if title is not None: plt.suptitle(title)
    plt.show()



spider(
    pd.DataFrame({
        'x': [*'abcde'],
        'c1': [10,11,12,13,14],
        'c2': [0.1, 0.3, 0.4, 0.1, 0.9],
        'c3': [1e5, 2e5, 3.5e5, 8e4, 5e4],
        'c4': [9, 12, 5, 2, 0.2],
        'test': [1,1,1,1,5]
    }),
    id_column='x',
    title='Sample Spider'
)

© www.soinside.com 2019 - 2024. All rights reserved.