Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plot and annotate from DataFrame with MultiIndex and multiple columns [closed]

I have a Pandas DataFrame that contains multiple columns and multiIndex. I would like to plot data from two columns(“Total” and ”Sold”) as different line charts and use the values from the third column “Percentage” as the text of the annotation for the points on the “Sold” chart. What is the best way to do it? Any advice and suggestions will be greatly appreciated.

#data is a dict
data = { 'Department': ['Furniture','Furniture','Furniture', 
'Gifts','Gifts','Gifts'],
           'Month':['May','June','July','May','June','July'],
           'Total':[2086,1740,1900,984,662,574],
            'Sold':[201,225,307,126,143,72],
            'Percentage':[10, 13, 16, 13, 22, 13]
         }
# DataFrame() turns the dict into a DataFrame
# Set up MultiIndex
df=pd.DataFrame(data)
df.set_index(['Department', 'Month'], inplace=True)
df

DataFrame

# Plot departments
departments=df.index.get_level_values(0).unique() 
for department in departments:
    ax=df.ix[department].plot(title=department,y=['Total','Sold'],
                        xlim=(-1.0, 3.0))

Plot from DataFrame

like image 461
Jel Avatar asked Jul 04 '26 23:07

Jel


1 Answers

You could achieve this in different ways.
I will just mention a couple, the most straightforward ones without the goal of being complete and I am sure there are many easier ways to do that.
One way involves the use of the method text.
In your case would be

ii = [0, 1, 2]  # the locations of the month labels, according to your plotting... I leave it to you to automatize or find a way to retrieve those
for department in departments:
  ax=df.ix[department].plot(title=department,y=['Total','Sold'], xlim=(-1.0, 3.0))
  for c, months in enumerate(unique_list_of_months):  # in your case would be ['May', 'June', 'July']
    ax.text(ii[c], df.ix[department]['Sold'][c], str(df.ix[department]['Percentage'][c]) + '%')

The other method involves the use of annotate. Leaving out some for loops as above, you would replace the call to ax.text with something like

ax.annotate(str(df.ix[department]['Percentage'][months]) + '%',
        (ii[c], df.ix[department]['Sold'][months]),
        xytext=(0, 0),
        textcoords='offset points')

Of course you can tweak positions, font size, etc.
For an intro to annotations, please consult the official webpage: Matplotlib annotations

Here the resulting plots I get:
Gifts plot Furniture plot

like image 98
fedepad Avatar answered Jul 07 '26 13:07

fedepad



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!