Search code examples
pythonmatplotlibseabornline

How to label end of lines of plot area (Seaborn or Matplotlib)


sorry for asking but for the third day in a row I cannot figure out how to label all country names in a plot with yearly Energy consumption data just at the end of the plot like e.g. this eg in Financial times: label end of lines outside of plot area.

I am the very begginer so appreciate your responce so much!!!

I've noticed some people used 'for i in list' or quite lenghty formulas to name all items in the list, but doesn't work in my hands now.

Here is my code:

d=pd.read_csv('/kaggle/input/world-energy-consumption/World Energy Consumption.csv')
d.iloc[:, [1, 2, 9, 13, 20, 43, 51, 60, 69, 75, 82, 108, 106, 92, 102, 41-42]]
df=d.fillna(method='ffill').fillna(method='bfill')
plt.figure(figsize=(20,20))
sns.lineplot(data=df, x='year', y='energy_cons_change_pct', hue='country', size=15, style='country', legend='brief')
plt.xlabel('Year')
plt.ylabel('energy_cons_change_pct')

MANY THANKS IN ADVANCE!


Solution

  • Not perfect but here is the idea using ax.text(...):

    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    df = pd.read_csv("https://github.com/owid/energy-data/raw/master/owid-energy-data.csv")
    
    year_start, year_end = 2000, 2020
    countries = ("Afghanistan", "Bhutan", "Cambodia", "Denmark", "Egypt", "Finland")
    column = "energy_cons_change_pct"
    
    df_ = df.copy()
    df_ = df_[df_["country"].isin(countries)]
    df_ = df_[df_["year"] >= year_start]
    df_ = df_[df_["year"] <= year_end]
    df_ = df_.fillna(method="ffill").fillna(method="bfill")
    
    
    fig, ax = plt.subplots(figsize=(20, 20))
    
    sns.lineplot(
        data=df_,
        x="year",
        y=column,
        hue="country",
        style="country",
        legend=False,
        ax=ax,
    )
    
    last_values = df_[["country", column]][df_["year"] == year_end]
    
    for country, value in last_values.itertuples(index=False):
        ax.text(x=year_end + 0.2, y=value, s=country, va="center")
    
    ax.grid()
    ax.spines["top"].set_visible(False)
    ax.spines["right"].set_visible(False)
    ax.spines["bottom"].set_visible(False)
    ax.spines["left"].set_visible(False)
    ax.set_xticks(np.arange(year_start, year_end + 1))
    ax.set_xlim([None, year_end + 0.2])
    
    plt.show()
    

    Legend on lines