I am trying to replicate this: enter image description here

我已经走得很远了:

import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
import numpy as np
import pandas as pd


colors = ["#CC5A43","#CC5A43","#2C324F"]

data = {
    "year": [2004, 2022, 2004, 2022, 2004, 2022],
    "countries" : [ "Denmark", "Denmark", "Norway", "Norway","Sweden", "Sweden",],
    "sites": [4,10,5,8,13,15]
}
df= pd.DataFrame(data)
df = df.sort_values(['countries' ,'year' ], ascending=True ).reset_index(drop=True)
df['ctry_code'] = df.countries.astype(str).str[:2].astype(str).str.upper()
df['year_lbl'] ="'"+df['year'].astype(str).str[-2:].astype(str)
df['sub_total'] = df.groupby('year')['sites'].transform('sum')
no_bars = df.sub_total.max()
sub_totals = df.sub_total.unique()
years= df.year.unique()
fig, axes = plt.subplots(nrows=2, ncols=1,figsize=(6, 6), subplot_kw=dict(polar=True))
fig.tight_layout(pad=3.0)

colors = [["#CC5A43"]*4 +["#2C324F"]*5 + ["#5375D4"]*13,
          ["#CC5A43"]*10 +["#2C324F"]*8 + ["#5375D4"]*15]

for sub_total, year,color,ax in zip( sub_totals, years,colors,axes.ravel()):
        angles =  np.arange(0,2*np.pi,2*np.pi/sub_total)
        ax.plot([angles, angles],[0,1],lw=4, c="#CC5A43")
        ax.set_rorigin(-4)
        ax.set_theta_zero_location("N")
        ax.set_yticklabels([])
        ax.set_xticklabels([])
        ax.grid(False)
        ax.spines[['polar','inner']].set_color('w')
        ax.text(np.pi/2,-3.2, year,va="center" )
        for i, j in enumerate(ax.lines):
                j.set_color(color[i])

#add legend
color_legend = [ "#A54836", "#5375D4", "#2B314D",]
lines = [Line2D([0], [0], color=c, linestyle='-', lw=4,) for c in color_legend]
labels = df.countries.unique().tolist()
plt.legend(lines, labels,
           bbox_to_anchor=(1.5, -0.02), loc="lower center",
            frameon=False, fontsize= 10)

which produces: enter image description here

但我真的在挠头,不知道如何做注解的"箭头":

enter image description here

我希望‘-(’能行得通,但它不行.

我的问题是,我需要为这个创建我自己的arrwostyle(这是一个好的参考资料吗?),或者有没有更明显的方法来做,而我完全错过了它?

推荐答案

你可以在极轴上画一条线,得到这样的结果.但请注意,您不能只定义终点,它仍然会绘制为一条直线.有关更多信息,请参见How to draw a curved line/arc in a polar plot with matplotlib?.

因此,我们可以在我们想要的两个Angular 之间定义一个点数组,具有恒定的径向距离.

for sub_total, year,color,ax in zip( sub_totals, years,colors,axes.ravel()):
        angles =  np.arange(0,2*np.pi,2*np.pi/sub_total)
        ax.plot([angles, angles],[0,1],lw=4, c="#CC5A43")
        ax.set_rorigin(-4)
        ax.set_theta_zero_location("N")
        ax.set_yticklabels([])
        ax.set_xticklabels([])
        ax.grid(False)
        ax.spines[['polar','inner']].set_color('w')
        ax.text(np.pi/2,-3.2, year,va="center" )
        for i, j in enumerate(ax.lines):
                j.set_color(color[i])

        # this is what I added:
        angle1, angle2 = np.pi/4, 1.4*np.pi/4
        anglemid = np.mean([angle1, angle2])
        anglerange = np.arange(angle1, angle2, 0.001)
        r = np.ones_like(anglerange) * 2
        ax.plot(anglerange, r, lw=1, c="grey", clip_on=False)
        ax.plot([anglemid, anglemid], [2, 2.5], lw=1, c="grey", clip_on=False)

        ax.set_rmax(1)

注意:我将rmax设置为1,以确保原始绘图不会更改.

将angle1和angle2修改为所需的值.

您需要为线条定义clip_on=False,以允许它们显示在绘图区之外(即,使用r>;rmax).

enter image description here

Python相关问答推荐

Matlab中是否有Python的f-字符串等效物

重新匹配{ }中包含的文本,其中文本可能包含{{var}

从收件箱中的列中删除html格式

输出中带有南的亚麻神经网络

如何让程序打印新段落上的每一行?

基于字符串匹配条件合并两个帧

如何在Python脚本中附加一个Google tab(已经打开)

优化器的运行顺序影响PyTorch中的预测

在不同的帧B中判断帧A中的子字符串,每个帧的大小不同

替换现有列名中的字符,而不创建新列

OpenGL仅渲染第二个三角形,第一个三角形不可见

如何在Python中使用Iscolc迭代器实现观察者模式?

判断Python操作:如何从字面上得到所有decorator ?

使用SeleniumBase保存和加载Cookie时出现问题

Seaborn散点图使用多个不同的标记而不是点

按条件计算将记录拆分成两条记录

如何在Python中创建仅包含完整天数的月份的列表

将相应的值从第2列合并到第1列(Pandas )

极点用特定值替换前n行

将多行数据循环到嵌套框架中的单行