我正在制作一个极坐标图,其中的刻度不是均匀分布在圆上。有几个非常好的Q&A对处理均匀分布的答案,它们都使用 divide-up-the-circle 方法。E.g. this。
我想知道是否可以使用烘焙到标签中的转换来旋转文本,使其按照我想要的方式放置。
我可以做到这一点,但我不知道如何正确地锚它。代码是这样的:
for tick in plt.xticks()[1]:
tick._transform = tick._transform + mpl.transforms.Affine2D().rotate_deg_around(0, 0, 10)
它给出如下输出:
而我想要这样的输出:
(from上述相关问题)
显然,我需要90°旋转,而不是10°,但90°旋转它离开画布。
这种方法可行吗?或者我需要重新评估我的策略吗?
完整的代码块在这里:
import random
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
one_person = {
"Human": {
"Collaboration": 4,
"Growth Mindset": 3,
"Inclusion": 5,
"Project and Studio Life": 2,
},
"Tectonics": {
"Office Manual and Procedures": 3,
"Documentation Standards": 3,
"Site Stage Services": 2,
"External and Public Domain Works": 2,
"Structure": 3,
"Enclosure": 2,
"Waterproofing (int. and ext.)": 3,
"Interiors": 1,
"Structure and Services": 2,
},
"Technology": {
"Bluebeam": 2,
"Confluence": 3,
"Drawing on screens": 0,
"dRofus": 0,
"Excel": 2,
"Grasshopper": 1,
"InDesign": 2,
"Outlook": 2,
"Python": 5,
"Rhino": 1,
"Teams": 2,
"Timesheets and expenses": 3,
},
"Regenerative": {
"REgenerative Design": 3,
"Materials and Embodied Carbon practice": 1,
"Materials and Embodied Carbon analysis": 2,
"Energy": 3,
"Resilience": 1,
"Rating Systems": 2,
},
"Design": {
"Predesign - Briefing, Stakeholder Engagement & Establishing Project Values": 2,
"Predesign - Feasibility Studies And Strategic Organisational Planning": 3,
"Initiating Design": 2,
"Conserving Design": 3,
"Design Communication - Written": 2,
"Design Communication - Visual": 4,
"Design Communication - Verbal": 3,
},
"Connecting with country": {"Connecting with Country": 2},
}
colours = [
"b", # blue.
"g", # green.
"r", # red.
"c", # cyan.
"m", # magenta.
"y", # yellow.
"k", # black.
# "w", # white.
]
def draw_radar(data, colour_letters, person_name=""):
"""Draw the graph.
Based substantially on this SO thread:
https://stackoverflow.com/questions/60563106/complex-polar-plot-in-matplotlib
"""
# not really sure why -1, but if you don't you get an empty segment
num_areas = len(data) - 1
running_total = 0
thetas = {}
for key, value in data.items():
this_area_num_points = len(value)
this_area_theta = ((2 * np.pi) / num_areas) / (this_area_num_points)
thetas[key] = []
for i in range(len(value)):
thetas[key].append((i * this_area_theta) + running_total)
running_total += (2 * np.pi) / num_areas
labels = []
for key, value in data.items():
for area, score in value.items():
labels.append(f"{score} {key}: {area}")
for name, theta_list in thetas.items():
individual_scores = list(data[name].values())
colour = random.choice(colour_letters)
if len(theta_list) > 1:
plt.polar(theta_list, individual_scores, c=colour, label=name)
elif len(theta_list) == 1:
plt.scatter(theta_list, individual_scores, c=colour, label=name)
plt.yticks(np.arange(-5, 5), [""] * 5 + list(range(5)))
plt.xticks(
np.concatenate(tuple(list(thetas.values()))),
labels,
transform_rotates_text=True,
)
for tick in plt.xticks()[1]:
tick._transform = tick._transform + mpl.transforms.Affine2D().rotate_deg_around(
0, 0, 10
)
if person_name:
plt.title = f"Competency for {person_name}"
plt.savefig("radar.png")
draw_radar(one_person, colours)
1条答案
按热度按时间svmlkihl1#
不使用Matplotlib转换,您可以使用
ax.get_xticklabels()
,然后使用label.set_rotation(θ¹)
迭代地为每个标签设置特定于刻度的旋转**<$**其中,Angular θ源自与每个标签相关的极坐标数据;实际上等效于极坐标图中的
x
维度(即圆形网格线)。例如,修改您提供的代码,如下所示:
结果:x1c 0d1x
您可能需要调整以下设置:
figsize
(在fig
和ax
图形和轴对象的定义中),相应地,y_adjust
因子(设置为0.8以上)。一般逻辑是为每个极坐标数据值找到绘制的thetaAngular ,然后将该Angular 值本身用作标注文本的刻度特定旋转。
np.cos
代码将检查并适当旋转倒置标注。每个标注将向外移动(即,在y
-维度上为负[即,* 径向 *;或者换句话说,在圆的外部&在任何可能的半径的方向上])增加一个基于其标准化标签文本长度的量(相对于最大长度标签),导致所有标签或多或少精确地位于圆外部(即,文本标签越长,它必须移动和移动得越多)。此外,还有一个标签(以“Country”结尾),与另一个标签重叠-对于那个标签,我自定义将其向上移动,并稍微弯曲其刻度标签旋转的Angular ,以反映它实际上属于/应该指向极坐标图上与其下方刻度标签数据具有相同θ角的数据。