首页 > 解决方案 > 让雷达条形图列跨越条形的整个宽度 - Matplotlib

问题描述

一个善良而聪明的人为我设计了一个漂亮的 matplotlib 雷达图。然而,这里的问题是图表上的柱线没有延伸到它们超过的给定 ytick 之下。理想情况下,高于 1.0 的每个值的条将向下延伸到中心,而不是留下间隙。

我确信这里必须有一个简单的修复,但我非常喜欢在 matplotlib 中创建雷达图的艺术。

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111, polar=True)

sample = [
    35.417256011315416,
    0.028288543140028287,
    1.3578500707213579,
    3.3663366336633667,
    0.8203677510608205,
    35.445544554455445,
    3.3946251768033946,
    19.46251768033946,
    0.7072135785007072,
]

N = len(sample)

theta = np.arange(0, 2 * np.pi, 2 * np.pi / N)
bars = ax.bar(theta, np.log10(sample), width=0.4)
ax.set_xticks(theta)
#ax.set_xticklabels(range(1, len(theta) + 1))
ax.set_xticklabels(['Delayed\nExecution', 'File\nOpening', 'Firewall\nModification', 'Permission\nModification', 'Persistence', 'Proxied\nExecution', 'Reconnaissance', 'Registry\nModification', 'Task\nStopping'])
ax.yaxis.grid(True)
precision = 2  # Change to your desired decimal precision

ax.set_yticklabels([str(round(10 ** x, precision)) for x in ax.get_yticks()])
#plt.ioff()
plt.show()

在此处输入图像描述

标签: python-3.xmatplotlibradar-chart

解决方案


问题出在您的数据上,它np.log10(sample)返回一个包含正值和负值的数组,因此,一些条形图没有扩展。为了让所有条形图从同一水平开始,您可以首先缩放samples以使最小量级为非负数,

get_mag = lambda x: 10**min(np.floor(np.log10(x)))
sample = np.array(sample) / get_mag(sample)

通过缩放sample,您可以绘制数据

get_mag = lambda x: 10**min(np.floor(np.log10(x)))
init_mag = get_mag(sample)
sample = np.array(sample) / get_mag(sample)
N = len(sample)

theta = np.arange(0, 2 * np.pi, 2 * np.pi / N)
bars = ax.bar(theta, np.log10(sample), width=0.4)
ax.set_xticks(theta)
#ax.set_xticklabels(range(1, len(theta) + 1))
ax.set_xticklabels(['Delayed\nExecution', 'File\nOpening', 'Firewall\nModification', 'Permission\nModification', 'Persistence', 'Proxied\nExecution', 'Reconnaissance', 'Registry\nModification', 'Task\nStopping'])

dat = np.log10(sample)
ax.set_ylim(0,max(dat))
ax.yaxis.grid(True)
precision = 2  # Change to your desired decimal precision

ax.set_yticklabels([str(round((10 ** x) * init_mag, precision)) for x in ax.get_yticks()])
#plt.ioff()
plt.show()

输出是

输出

请注意,我还修改了 yticks 的标签

ax.set_yticklabels([str(round((10 ** x) * init_mag, precision)) for x in ax.get_yticks()])

推荐阅读