在Python中绘制饼图雷达图(披萨片)。

3
我想在Python中生成一个带有14个单独类别或“比萨片”饼形雷达/蜘蛛图。类似于Excel中创建的此示例或使用ggplot2创建的此示例

这个plt示例很有用(下面是代码),但是不同类别的观测值通过线连接在一起,而不是拥有它们自己的独立部分(“比萨片”)。有什么想法在Python中如何实现呢?

import matplotlib.pyplot as plt
import pandas as pd
from math import pi
 
df = pd.DataFrame({
'group': ['A','B'],
'r1': [2, 23],
'r2': [5, 5],
'r3': [1, 9],
'r4': [1, 1],
'r5': [3, 6],
'r6': [0, 0],
'r7': [17, 53],
'r8': [29, 44],
'r9': [0,2],
'r10': [0, 2],
'r11': [0, 3],
'r12': [1, 2],
'r13': [0, 3],
'r14': [0, 0],    
})
 
categories=list(df)[1:]
N = len(categories)     
angles = [n / float(N) * 2 * pi for n in range(N)]
angles += angles[:1]     
fig = plt.figure(figsize=(6,6))
ax = plt.subplot(111, polar=True)
ax.set_theta_offset(pi / 2)
ax.set_theta_direction(-1)
plt.xticks(angles[:-1], categories)#, rotation=70)
 
# Draw ylabels
ax.set_rlabel_position(10)
plt.yticks([20,40,60,80,100], ["20","40","60","80","100"], color="black", size=8)
plt.ylim(0,100)
 
values=df.loc[0].drop('group').values.flatten().tolist()
values += values[:1]
ax.plot(angles, values, linewidth=1, linestyle='solid', label="A")
ax.fill(angles, values, 'b', alpha=0.7)
 
values=df.loc[1].drop('group').values.flatten().tolist()
values += values[:1]
ax.plot(angles, values, linewidth=1, linestyle='solid', label="B")
ax.fill(angles, values, 'r', alpha=0.1)     
plt.legend(loc='upper right', bbox_to_anchor=(0, 0))

enter image description here

1个回答

4

在雷达图中,通常值是沿着圆形轴每个刻度点一次,通过连接线形成锯齿形图案的。极坐标条形图可能更接近所需的图表。

极坐标条形图类似于普通条形图,但弯曲在一个圆圈上。

为了使条和标签很好地在网格线之间,θ 位置可以移动半个条宽。可以使用次要刻度来将网格线恢复到其原始位置。

为了保持一致性,下面的代码还将一些对 plt. 的调用更改为 ax.

import matplotlib.pyplot as plt
from matplotlib.ticker import FixedLocator
import pandas as pd
from math import pi
import numpy as np

df = pd.DataFrame({'group': ['A', 'B'], 'r1': [2, 23], 'r2': [5, 5], 'r3': [1, 9], 'r4': [1, 1], 'r5': [3, 6], 'r6': [0, 0], 'r7': [17, 53], 'r8': [29, 44], 'r9': [0, 2], 'r10': [0, 2], 'r11': [0, 3], 'r12': [1, 2], 'r13': [0, 3], 'r14': [0, 0], })

categories = list(df)[1:]
N = len(categories)
angles = np.linspace(0, 2 * pi, N, endpoint=False)
angles_mids = angles + (angles[1] / 2)

fig = plt.figure(figsize=(6, 6))
ax = plt.subplot(111, polar=True)
ax.set_theta_offset(pi / 2)
ax.set_theta_direction(-1)
ax.set_xticks(angles_mids)
ax.set_xticklabels(categories)
ax.xaxis.set_minor_locator(FixedLocator(angles))

# Draw ylabels
ax.set_rlabel_position(0)
ax.set_yticks([20, 40, 60, 80, 100])
ax.set_yticklabels(["20", "40", "60", "80", "100"], color="black", size=8)
ax.set_ylim(0, 100)

values0 = df.loc[0].drop('group').values
ax.bar(angles_mids, values0, width=angles[1] - angles[0],
       facecolor='b', alpha=0.7, edgecolor='k', linewidth=1, label="A")

values1 = df.loc[1].drop('group').values
ax.bar(angles_mids, values1, bottom=values0, width=angles[1] - angles[0],
       facecolor='r', alpha=0.7, edgecolor='k', linewidth=1, label="B")

ax.grid(True, axis='x', which='minor')
ax.grid(False, axis='x', which='major')
ax.grid(True, axis='y', which='major')
ax.legend(loc='upper left', bbox_to_anchor=(0.9, 1))
plt.show()

example plot


厉害的@JohanC。对于那些不想将A组和B组的观察结果相加,而是希望将它们重叠在一起的人:ax.bar(angles_mids, values1, bottom=values0, width=angles[1] - angles[0], facecolor='r', alpha=0.7, edgecolor='k', linewidth=1, label="B") - user1442363

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接