Annotate some line plot observations

Viewed 149

I've created a script that displays 3 lines in a single line graph data points across 53 weeks. The graph works and labels display, but they're overcrowded. Does anyone know how to enumerate the annotate/data labels so only the even weeks display data labels? Below is my problem:

Graph1

import pandas as pd
import matplotlib.pyplot as plt

CA_plot_df = CA_Data.pivot_table('ED Arrivals', ['W'], 'Year').reset_index()
CA_plot_df = CA_plot_df[1:-1]
df_2021 = CA_plot_df[['W',2021]].dropna()[:-1]

plt.style.use('ggplot')
plt.rcParams['axes.facecolor'] = 'white'

fig = plt.figure(figsize = (15,8))
ax = fig.add_subplot(111)

plt.plot(CA_plot_df.W, CA_plot_df[2019], label = 'year 2019', color = '#407c38', linewidth = 2)

for i,j in zip(CA_plot_df.W,CA_plot_df[2019]):
    ax.annotate('%s' %round(j), xy=(i,j), xytext=(-2,5), textcoords='offset points')

plt.plot(CA_plot_df.W, CA_plot_df[2020], label = 'year 2020', color = '#b3b3b3', linewidth = 2)
plt.plot(df_2021.W, df_2021[2021], label = 'year 2021',color = '#d64550', linewidth = 2)

for i,j in zip(df_2021.W,df_2021[2021]):
    ax.annotate('%s' %round(j), xy=(i,j), xytext=(-2,5), textcoords='offset points')
1 Answers
  • The easiest option is probably to add a condition when adding the annotations.
  • In the following case, only add the annotation when the enumerate value is even.
for e, i, j in enumerate(zip(CA_plot_df.W, CA_plot_df[2019])):
    if e%2 == 0:
        ax.annotate('%s' %round(j), xy=(i,j), xytext=(-2,5), textcoords='offset points')


for e, i, j in enumerate(zip(df_2021.W, df_2021[2021])):
    if e%2 == 0:
        ax.annotate('%s' %round(j), xy=(i,j), xytext=(-2,5), textcoords='offset points')

Working Example

  • Tested with pandas 1.3.0 and matplotlib 3.4.2
import pandas as pd
import seaborn as sns  # for data only

# sample data; top 50 rows
df = sns.load_dataset('tips').loc[:50, ['total_bill', 'tip']]

# add plots
ax = df.plot(y='total_bill', marker='.', xlabel='Records', ylabel='Amount ($)', figsize=(15, 8))
df.plot(y='tip', marker='.', ax=ax)

# adds every other annotation
for e, (i, j) in enumerate(df[['total_bill']].iterrows()):
    if e%2 == 0:
        ax.annotate(f'{j.values[0]:0.1f}', xy=(i, j), xytext=(-2, 5), textcoords='offset points')
        
# adds every annotation
for e, (i, j) in enumerate(df[['tip']].iterrows()):
    ax.annotate(f'{j.values[0]:0.1f}', xy=(i, j), xytext=(-2, 5), textcoords='offset points')

enter image description here

Related