3

I'm new to Python and I'm trying to plot some data with the help of matplotlib.

I'm trying to group the data but the problem is that the groups overlap each other. Here is a picture which describes my problem: Problem

Problem

Here is my code:

import numpy as np
import matplotlib.pyplot as plt

n_groups = 3
credits = (market[0], market[1], market[2])
debits = (dmarket[0], dmarket[1], dmarket[2])
profits = (pmarket[0], pmarket[1], pmarket[2])
fig, ax = plt.subplots()
index = np.arange(n_groups)
bar_width = 0.45
opacity = 0.4
error_config = {'ecolor': '0.3'}

rectsCredits = plt.bar(index, credits, bar_width,
                 alpha=opacity,
                 color='b',
                 error_kw=error_config,
                 label='Credit')

rectsDebits = plt.bar(index + bar_width, debits, bar_width,
                 alpha=opacity,
                 color='r',
                 error_kw=error_config,
                 label='Debit')

rectsProfits = plt.bar(index + 2*bar_width, profits, bar_width,
                 alpha=opacity,
                 color='g',
                 error_kw=error_config,
                 label='Profits')

plt.xticks(index + bar_width/2, ('Tariff Market', 'Wholesale Market', 'Balancing Market'))
plt.legend()
plt.tight_layout()

def autolabel(rects):
    """
    Attach a text label above each bar displaying its height
    """
    for rect in rects:
        height = rect.get_height()
        ax.text(rect.get_x() + rect.get_width() / 2.,
                1.01 * height,
                '%d' % int(height),
                ha='center', va='bottom')

autolabel(rectsCredits)
autolabel(rectsDebits)
autolabel(rectsProfits)

plt.show()

I don't know what to do. I think there is only a little logic problem which I don't see right now!

4
  • 2
    It would be helpful if you included the actual values for the market, dmarket values so the example can be run as-is. I've included the missing imports but you have to supply the actual values. If possible could you include an "expected output" image? Commented Jan 6, 2018 at 14:23
  • 1
    Besides: A more descriptive title would be good so potential answerers and future visitors with the same problem can find the question more easily. Commented Jan 6, 2018 at 14:25
  • Okay unfortunately the image was not uploaded ! Give me another try! Thanks for your advice I will consider it in the future! Commented Jan 6, 2018 at 14:27
  • Thanks ! Yes exactly. And thats the problem ! I want to add some margin between the groups Commented Jan 6, 2018 at 14:30

1 Answer 1

3

The position of the bars is a bit off. You insert the first label group at [0, 1, 2] (index), the second on [0.45, 1.45, 2.45] (index + bar_width) and the third at [0.9, 1.9, 2.9] (index + 2*bar_width). Each bar has a width of 0.45 so no wonder these overlap.

For the following part I chose just some data for visualization, you have to insert or use the correct values.

If you change bar_width to 1/3 then there's no empty space between the groups:

bar_width = 1 / 3

enter image description here

If you choose something like 1/4 then it will have exactly the space for one additional bar between each group:

bar_width = 1 / 4

enter image description here

But the label isn't centered correctly yet, but that can be easily fixed by using a new index in plt.xticks:

bar_width = 1 / 4
plt.xticks(index + bar_width, ('Tariff Market', 'Wholesale Market', 'Balancing Market'))

enter image description here

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

5 Comments

Thanks ! I knew that it was just a little mistake which cost me nearly 2 hours :D But what if I want to make the bars wider?
As long as the bar width is smaller or equal to 1 / number_of_bars_in_group you won't have overlap. The 1 is there because that's the space between two distinct groups.
Okay. But sometimes you need to make it wider than 1. For example if I add some labels like you do in your examples like "10 000" or even bigger numbers. These numbers would overlap each other if the bars have only a width <1.
You choose a "distance" of 1 between groups by using index = np.arange(3). If you want a distance of 2 you should be using [0, 2, 4] (for example index = np.arange(n_groups) * 2), in that case you also need to double the barwidth. However matplotlib will always scale the image, so probably making the fontsize of the labels smaller will be the smarter move.
Okay now I get it ! Thank you very much !!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.