3

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

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Jel
  • 31
  • 2
  • I guess you need to explain further what you want to achieve. Describe what the final plot should look like. – ImportanceOfBeingErnest Aug 13 '17 at 10:44
  • I am trying to have the final plot as the shown above and the three points of the bottom line("Sold") having the annotation as "10% "; "13%" ,"16%" in the plot "Furniture" and "13%", "22%", "13%" in the plot "Gifts" respectevely. – Jel Aug 13 '17 at 12:17
  • @ImportanceOfBeingErnest After his comment is pretty clear what he wants to obtain. Should I edit the question to include his comment? Or he can do that.... – fedepad Aug 13 '17 at 21:32
  • That was indeed the information missing. This question has been asked already [here](https://stackoverflow.com/questions/22272081/label-python-data-points-on-plot) and has several answers. Technically, one may thus edit the question, reopen it, then close it again as duplicate. Or we may just leave it as it is. – ImportanceOfBeingErnest Aug 14 '17 at 08:25

1 Answers1

1

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

fedepad
  • 4,509
  • 1
  • 13
  • 27
  • It is fantastic, a huge thank you, hats off. i wish one day to be an expert like you fedepad.Respect – Jel Aug 13 '17 at 21:24