我想通过使用subplot绘制2个图形。 我有一个数据框(simple_line_final_df)
Madagascar Covid-19 Totaly olona
Daty
2020-05-20 Marary 371
2020-05-20 Sitrana 131
2020-05-20 Tsaboana 238
2020-05-21 Marary 405
2020-05-21 Sitrana 131
... ... ...
2020-06-28 Sitrana 944
2020-06-28 Tsaboana 1116
2020-06-29 Marary 2138
2020-06-29 Sitrana 966
2020-06-29 Tsaboana 1152
我的目标是在lineplot中显示最后一个值(图1):
具有以下代码:
fig ,axes = plt.subplots(ncols=1,nrows=2,constrained_layout=True)
# # ------------------------------Plot first figure --------------------------------------------
palette = ['#F70A0A','#2A930C','#930C85']
sns.set(rc={'figure.figsize':(30,15)},palette= palette, font_scale=1.7)
# # pour les axes
ax1 = sns.lineplot(x=simple_line_final_df.index,y= 'Totaly olona',data=simple_line_final_df,hue='Madagascar Covid-19',style='Madagascar Covid-19',markers=True,dashes=False,ax=axes[0])
# style
sns.set_style("darkgrid" , {"ytick.major.size": 10 , "ytick.minor.size": 2 , 'grid.linestyle': '--'})
plt.xticks(rotation=90)
plt.xlabel('Daty', fontsize = 20)
plt.ylabel('Totaly olona', fontsize = 20)
plt.minorticks_on()
plt.legend(loc='upper left')
plt.grid(b=True, which='minor', color='#999999', linestyle='-', alpha=0.2 , axis='y')
ax1.set_ylim(0)
last_index = simple_line_final_df.last_valid_index()
ax1.set_xlim(simple_line_final_df.first_valid_index(),simple_line_final_df.last_valid_index())
# -----------------Put annotation ----------
# for line , name in zip (ax1.lines ,simple_line_final_df['Madagascar Covid-19']):
# y = line.get_ydata()[-1]
# #ax.annotate(y,xy=(1,y),xytext=(6,0),color=line.get_color(),size=14,xycoords = ax.get_yaxis_transform(),textcoords ="offset points")
# ax1.annotate(y,xy=(last_index,y),color=line.get_color())
# ------------------------------Plot second figure barplot --------------------------------------------
sns.set(rc={'figure.figsize':(30,15)},palette=['#F70A0A','#2A930C','#930C85'], font_scale=1.7)
# pour les axes
ax = sns.barplot(x=df_final_seaborn.index,y='Isan\'ny olona',data=df_final_seaborn,hue='Covid-19 Madagascar',ax=axes[1])
sns.set_style("darkgrid" , {"ytick.major.size": 10 , "ytick.minor.size": 2 , 'grid.linestyle': '--'})
plt.xticks(rotation=90)
plt.xlabel('Daty', fontsize = 20)
plt.ylabel('Isan\'ny olona', fontsize = 20)
plt.minorticks_on()
plt.legend(loc='upper left')
plt.grid(b=True, which='minor', color='#999999', linestyle='-', alpha=0.2 , axis='y')
ax.xaxis.set_major_formatter(plt.FixedFormatter(df_sea.index.to_series().dt.strftime("%Y-%m-%d")))
for patch in ax.patches:
x , width , height = patch.get_x(),patch.get_width(),patch.get_height()
color = patch.get_facecolor()
#ignore . and nan values
if height is None or height ==0:continue
ax.text(x+width/2,height+0.1,height.astype(int),ha='center',color=color)
plt.show()
结果是:
:No handles with labels found to put in legend.
如您所见,它不会显示最后一个值,因为我在注释中添加了批注代码
但是当我通过取消注释注释部分添加以下代码时:
# -----------------Put annotation ----------
for line , name in zip (ax1.lines ,simple_line_final_df['Madagascar Covid-19']):
y = line.get_ydata()[-1]
ax1.annotate(y,xy=(last_index,y),color=line.get_color())
结果是图2消失了:
问题是这一行:y = line.get_ydata()[-1]
我尝试通过以下代码来解决注释:首先获取最后一个值(索引错误)而不是最后一个
for x , y in zip(simple_line_final_df.index,simple_line_final_df['Totaly olona'].loc[simple_line_final_df.last_valid_index()]):
print(x,y)
#ax.annotate(y,xy=(1))
#ax.annotate(y,xy=(x,y),color=line.get_color())
ax.text(x,y,f'{y:.2f}')
出:
2020-05-20 00:00:00 2138
2020-05-20 00:00:00 966
2020-05-20 00:00:00 1152
以下是解决方法:
palette = ['#F70A0A','#2A930C','#930C85']
sns.set(rc={'figure.figsize':(30,15)},palette= palette, font_scale=1.7)
# Plot lines
ax = sns.lineplot(x=simple_line_final_df.index,y= 'Totaly olona',data=simple_line_final_df,hue='Madagascar Covid-19',style='Madagascar Covid-19',markers=True,dashes=False)
# styling figure
#sns.set_style("darkgrid" , {"ytick.major.size": 10 , "ytick.minor.size": 2 , 'grid.linestyle': '--'})
ax.set_ylim(0)
ax.set_xlim(simple_line_final_df.first_valid_index(),simple_line_final_df.last_valid_index())
#ax.set_ylim(simple_line_final_df.last_valid_index())
plt.xticks(rotation=90)
plt.xlabel('Daty', fontsize = 20)
plt.ylabel('Totaly olona', fontsize = 20)
plt.minorticks_on()
plt.legend(loc='upper left')
plt.grid(b=True, which='minor', color='#999999', linestyle='-', alpha=0.2 , axis='y')
# for annotation
for value in ax.lines:
y = value.get_ydata()
if len(y)>0:
ax.annotate(f'{y[-1]:.2f}',xy=(1,y[-1]),xycoords=('axes fraction','data'),ha='left',va='center',color=value.get_color())
plt.show()
答案 0 :(得分:2)
lineplot
创建一些用于图例的空Line2D对象,因此line.get_data()
返回一个空数组。如果您查看ax1.lines
,应该看到它包含6-7个对象,而不是您期望的3个。一种解决方法是在提取数据之前测试该行是否为空:
fmri = sns.load_dataset('fmri')
ax1 = sns.lineplot(x="timepoint", y="signal", hue="event",
data=fmri, ci=None)
for l in ax1.lines:
y = l.get_ydata()
if len(y)>0:
ax1.annotate(f'{y[-1]:.2f}', xy=(1,y[-1]), xycoords=('axes fraction', 'data'),
ha='left', va='center', color=l.get_color())