Directly grouping rows from pandas.DataFrame through matplotlib plotting

Viewed 41

I have a Dataframe saved as a .csv file that is similar to the one produced by the following code:


dates = [["2022-03-31", "A",100], ["2022-03-31", "B",100],  ["2022-03-31", "C", 250], ["2022-04-31", "A", 500], ["2022-04-31", "B", 100], ["2022-04-31", "C", 200], ["2022-05-31", "A",200], ["2022-05-31", "B", 300], ["2022-05-31", "C", 500]]

df = pd.DataFrame(dates, columns=['Dates',"Payment Method", "Values"])

df.to_csv("example.csv",index=False)

What I am trying to do is to set each month of the year (in the "Dates" column) as a singular x axis tick using matplotlib.pyplot and create a line for each payment method ("Payment Method" column) with its corresponding values ("Values" column) on the y axis for each month on the x axis. So for the payment method a

How would I go about directly grouping the months in the "Dates" row and plot 3 different lines (for payment methods "A", "B" and "C") with their corresponding values for each month using pandas and matplotlib?

1 Answers

Here are two solutions. The first is using pandas only. Pandas makes it easy to plot data and the backend is matplotlib, too. The second solution uses matplotlib.

Data handling

Before I start, I want to comment, that I don't use [pd.groupby()], because in this case df.pivot() is more useful and brings your DataFrame into a nice shape like this

dates = [["2022-03-31", "A",100], ["2022-03-31", "B",100],  ["2022-03-31", "C", 250], ["2022-04-31", "A", 500], ["2022-04-31", "B", 100], ["2022-04-31", "C", 200], ["2022-05-31", "A",200], ["2022-05-31", "B", 300], ["2022-05-31", "C", 500]]
df = pd.DataFrame(dates, columns=['Dates',"Payment Method", "Values"])
df['Dates'] = df['Dates'].str[:7]
df_pivot = df.pivot('Dates', 'Payment Method', 'Values')

>>> df_pivot
Payment Method    A    B    C
Dates                        
2022-03         100  100  250
2022-04         500  100  200
2022-05         200  300  500

which is easy to plot for both solutions.

As long you dates are of type string, you could replace() or slice the strings to remove the days.

In gerneral I suggest to parse dates to a datetime object using pd.to_datetime().

df['Dates'] = pd.to_datetime(df['Dates'])
df['Dates'] = df['Dates'].dt.strftime('%Y-%m')

but this gives you an error, because "2022-04-31" is not a valid date. Maybe this is something you should think about.

Pandas plot

fig = df_pivot .plot.bar()

The fig variable is of type matplotlib.axes._subplots.AxesSubplot. As you can see, pandas uses matplotlib and if you want to make changes to this figure, this is still possible afterwards. I think there is no need to use plain matplotlib.

barplot after pivot

I am not sure if your want a bar plot, but you can switch to df_pivot.plot.line() or other methods, too.

Matplotlib

This solution is pretty much based on the matplotlib barplot example.

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(len(df_pivot))
width = 0.2 # the width of the bars

fig, ax = plt.subplots()

rects1 = ax.bar(x - width, df_pivot['A'], width, label='A')
rects2 = ax.bar(x, df_pivot['B'], width, label='B')
rects2 = ax.bar(x + width, df_pivot['C'], width, label='C')

# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel('Value')
ax.set_title('Value by group and date')
ax.set_xticks(x, df.index)
ax.legend()

plt.show()

plain matplotlib example

As you can see, this needs some more lines of code.

Related