1

I have the following data:

1, method1, 3, type1, 73.9203
2, method1, 3, type1, 38.6353
3, method1, 3, type1, 38.0158
4, method1, 3, type1, 19.6426
5, method1, 3, type1, 52.3507
6, method2, 3, type2, 500.048
7, method2, 3, type1, 14.5179
8, method2, 3, type2, 500.029
9, method2, 3, type1, 267.738
10, method2, 3, type2, 500.008
11, method1, 4, type2, 500.036
12, method1, 4, type1, 271.698
13, method1, 4, type1, 309.884
14, method1, 4, type1, 103.91
15, method1, 4, type1, 478.43
16, method2, 4, type2, 500.071
17, method2, 4, type2, 500.033
18, method2, 4, type2, 500.151
19, method2, 4, type2, 500.09
20, method2, 4, type2, 500.009

I read those data using Python Pandas:

import pandas
import matplotlib.pyplot as plt

data_frames = pandas.read_csv("results2.txt", sep=r',\s+', engine = "python", header=None)
data_frames.columns = ["id", "method", "number", "type", "running_time"]

print(data_frames)

Which is successful:

    id   method  number   type  running_time
0    1  method1       3  type1       73.9203
1    2  method1       3  type1       38.6353
2    3  method1       3  type1       38.0158
3    4  method1       3  type1       19.6426
4    5  method1       3  type1       52.3507
5    6  method2       3  type2      500.0480
6    7  method2       3  type1       14.5179
7    8  method2       3  type2      500.0290
8    9  method2       3  type1      267.7380
9   10  method2       3  type2      500.0080
10  11  method1       4  type2      500.0360
11  12  method1       4  type1      271.6980
12  13  method1       4  type1      309.8840
13  14  method1       4  type1      103.9100
14  15  method1       4  type1      478.4300
15  16  method2       4  type2      500.0710
16  17  method2       4  type2      500.0330
17  18  method2       4  type2      500.1510
18  19  method2       4  type2      500.0900
19  20  method2       4  type2      500.0090

What I would like to do is to create a bar chart plot of the data:

  • x-axis: distinct numbers per method.
  • y-axis: number of types.

So I have the following code:

series = data_frames.groupby(["number", "method", "type"])["type"].count()

Which gives:

number  method   type
3       method1  type1    5
        method2  type1    2
                 type2    3
4       method1  type1    4
                 type2    1
        method2  type2    5
Name: type, dtype: int64

So the bar chart should look something like this: enter image description here

So basically, I want a bar chart that as x-axis values we have the distinct number per method each bar representing a stack of type of that method.

Before I found out that I can plot using matplotlib and pandas I was manually finding those values and then I was plotting as I wanted, but now that I see with Pandas you can have a more clean, readable and beautiful code I would like to do it in the best way possible.

What I have tried is:

ax = series.plot(kind='bar',
                 x="number",
                 y=["type", "method"],
                 legend=True)

plt.show()

But the result is not near of what I am looking for:

enter image description here

1 Answer 1

1
import matplotlib.pyplot as plt

suu = series.unstack(level=1).unstack() # Unstack, so that we can stack in the plot
methods = suu.columns.get_level_values('method').unique().tolist()[::-1] # Find the groups for the grouped plot
fig, ax = plt.subplots(1, 1) # Plot everything on 1 ax-object
for i, t in enumerate(methods[::-1]): # Select group
    # Stack types, plot one one ax-object
    suu[t].plot(kind='bar', stacked=True, position=i, color=['g', 'r'], ax=ax, 
       legend=i, width=0.25) # Only show one legend, and smaller bars so the groups don't touch

You want a stacked barchart, so you first need to unstack your groupby. You only want a partially stacked, partially grouped bar chart. So select the part of the dataframe that is in the one group. The stacked=True stacks the types, and the for-loop groups the methods. By selecting a position of 1 or 0, we can make sure they don't overlap, and by specifying a smaller width, we can make sure the groups are not directly next to each other. We don't want multiple legends, so only show a legend for one of the group.

Hope this helps

Output

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.