我试图将我的雷达图的标签与轴对齐,我遇到了困难。
当我将标签的前半部分(图的右侧)对齐设置为左侧时,对于后半部分,右侧的对齐设置为非“圆形”对齐
为此,我在xticklabels中循环并设置水平对齐。
# Draw one axe per variable + add labels labels yet
plt.xticks(angles, categories)
for label,i in zip(ax.get_xticklabels(),range(0,len(angles))):
if i<len(angles)/2:
angle_text=angles[i]*(-180/pi)+90
#label.set_horizontalalignment('left')
else:
angle_text=angles[i]*(-180/pi)-90
#label.set_horizontalalignment('right')
label.set_rotation(angle_text)
我想有一种正确的方法可以做到这一点,我无法弄明白,因为我不知道它是否应该考虑偏移,平移或如何调整极坐标来做到这一点。
感谢您的帮助
保
以下是完整代码以获取更多信息
from math import pi
import matplotlib.pyplot as plt
%matplotlib inline
import pandas as pd
## Generate Data
labels_test=[]
for i in range(0,40):
labels_test.append("Fooooooooo"+str(i))
pd_radar=pd.DataFrame(data=np.random.randint(low=0, high=10, size=(2, 40)),columns=labels_test)
# number of variable
categories=list(pd_radar)
N = len(categories)
# What will be the angle of each axis in the plot? (we divide the plot / number of variable)
angles = [n / float(N) * 2 * pi for n in range(N)]
# Initialise the spider plot
fig=plt.figure(figsize=(20,10))
ax = plt.subplot(111, polar=True)
# If you want the first axis to be on top:
ax.set_theta_offset(pi / 2)
ax.set_theta_direction(-1)
# Draw one axe per variable + add labels labels yet
plt.xticks(angles, categories)
for label,i in zip(ax.get_xticklabels(),range(0,len(angles))):
if i<len(angles)/2:
angle_text=angles[i]*(-180/pi)+90
label.set_horizontalalignment('left')
else:
angle_text=angles[i]*(-180/pi)-90
label.set_horizontalalignment('right')
label.set_rotation(angle_text)
# Draw ylabels
ax.set_rlabel_position(0)
# ------- PART 2: Add plots
# Plot each line of the data
# Ind1
values0=pd_radar.iloc[0].values.flatten().tolist()
ax.plot(angles, values0, linewidth=1, linestyle='solid', label="Label 1",color='yellow')
ax.fill(angles, values0, 'r', alpha=0.1,color='yellow')
# Ind2
values1=pd_radar.iloc[1].values.flatten().tolist()
ax.plot(angles, values1, linewidth=1, linestyle='solid', label="Label 2",color='deepskyblue')
ax.fill(angles, values1, 'r',color='deepskyblue', alpha=0.1)
# Add legend
plt.show()
答案 0 :(得分:1)
目前的代码does not run with matplotlib 2.2。以下解决方案适用于OP正在使用的2.0.2版。有关使用较新版本的变通方法,请参阅this question。
matplotlib中的文本有一个rotation mode。
旋转模式可以是"default"
,在这种情况下,首先旋转文本然后对齐
或者它可以是"anchor"
,在这种情况下,文本首先对齐然后旋转。
因此,为了让刻度标签在极坐标图上向外指向,您需要将文本的对齐方式设置为"left"
,然后将旋转模式设置为"anchor"
。
for label,rot in zip(ax.get_xticklabels(),ticks):
label.set_rotation(rot*180./np.pi)
label.set_horizontalalignment("left")
label.set_rotation_mode("anchor")
完整示例:
import numpy as np
import matplotlib.pyplot as plt
fig=plt.figure(figsize=(5,5))
ax = plt.subplot(111, polar=True)
ticks = np.linspace(0, 2*np.pi, 20, endpoint=False)
text = lambda : "".join(np.random.choice(list("manuladefil"), size=10))
labels = [text() for _ in range(len(ticks))]
plt.xticks(ticks, labels, size=16)
for label,rot in zip(ax.get_xticklabels(),ticks):
label.set_rotation(rot*180./np.pi)
label.set_horizontalalignment("left")
label.set_rotation_mode("anchor")
plt.tight_layout()
plt.show()
答案 1 :(得分:0)
我找到了一个看似不优雅的解决方案。主要思想是将垂直和水平对齐设置为角度的函数。
from math import pi
import matplotlib.pyplot as plt
%matplotlib inline
import pandas as pd
import numpy as np
## Generate Data
labels_test=[]
for i in range(0,40):
labels_test.append("Fooooooooo"+str(i))
pd_radar=pd.DataFrame(data=np.random.randint(low=0, high=10, size=(2, 40)),columns=labels_test)
# number of variable
categories=list(pd_radar)
N = len(categories)
# What will be the angle of each axis in the plot? (we divide the plot / number of variable)
angles = [n / float(N) * 2 * pi for n in range(N)]
# Initialise the spider plot
fig=plt.figure(figsize=(20,10))
ax = plt.subplot(111, polar=True)
# If you want the first axis to be on top:
ax.set_theta_offset(pi / 2)
ax.set_theta_direction(-1)
# Draw one axe per variable + add labels labels yet
# idea is to add both vertical and horizontal alignment as a function of pi
plt.xticks(angles, categories)
for label,i in zip(ax.get_xticklabels(),range(0,len(angles))):
angle_rad=angles[i]
if angle_rad <= pi/2:
ha= 'left'
va= "bottom"
angle_text=angle_rad*(-180/pi)+90
elif pi/2 < angle_rad <= pi:
ha= 'left'
va= "top"
angle_text=angle_rad*(-180/pi)+90
elif pi < angle_rad <= (3*pi/2):
ha= 'right'
va= "top"
angle_text=angle_rad*(-180/pi)-90
else:
ha= 'right'
va= "bottom"
angle_text=angle_rad*(-180/pi)-90
label.set_rotation(angle_text)
label.set_verticalalignment(va)
label.set_horizontalalignment(ha)
# Draw ylabels
ax.set_rlabel_position(0)
# ------- PART 2: Add plots
# Plot each line of the data
# Ind1
values2=pd_radar.iloc[0].values.flatten().tolist()
ax.plot(angles, values2, linewidth=1, linestyle='solid', label="Label 1",color='yellow')
ax.fill(angles, values2, 'r', alpha=0.1,color='yellow')
# Ind2
values3=pd_radar.iloc[1].values.flatten().tolist()
ax.plot(angles, values3, linewidth=1, linestyle='solid', label="Label 2",color='deepskyblue')
ax.fill(angles, values3, 'r',color='deepskyblue', alpha=0.1)
# Add legend
plt.show()