FAQ: Different Plot Types - Side-By-Side Bars

Im getting a syntax error it says I’m missing a ) I’m not sure why thought

n = 1  # This is our first dataset (out of 2)
t = 2 # Number of datasets
d = 6 # Number of sets of bars
w = 0.8 # Width of each bar
x_values = [t*element + w*n for element in range(d)]
plt.show()

When I type it like this:

n = 1  # This is our first dataset (out of 2)
t = 2 # Number of datasets
d = 6 # Number of sets of bars
w = 0.8 # Width of each bar
x_values = [t*element + w*n for element
             in range(d)]

I don’t get the error. Why is it different when in range(d)] is on a separate line?

Is it necessary to declare the t, d, and w variables again for the second set of bars? The values don’t change, and when I commented out the second set of declarations it didn’t change the results.

1 Like

Tip for x-labels: The exercise doesn’t tell you how to get the labels to center under the bars, but here’s how I did it.

Between plt.bar(store2_x,sales2) and plt.show(), put:

n=1.5
ax = plt.subplot()
ax.set_xticks([t*element + w*n for element
             in range(d)])
ax.set_xticklabels(drinks)
6 Likes

Thank you. I feel like this was a huge oversight on Code Academy’s part. Very disappointing.

1 Like

Just to add to this thread in addition to setting up the ticks for a bar chart: what the exercise also doesn’t specify is how to change the width of the bars themselves. I first was under the impression that that was includes in the statement regarding the placement of the bars (i.e. the w variable in the exercise).

However as is probably expected plt.bar() can take an additional parameter for width, so in this exercise plt.bar(store1_x, sales1, width=0.4) will create a narrower bar. The following code will align the tick in between the bars irrelevant of width, provided that the width is also updated in the w variable, and the alignment of the bars is left to its default of ‘centre’:

ar.set_xticks([(store1_x[i]+store2_x[i])/2 for i in range(d)])
ar.set_xticklabels(drinks)

Twan

2 Likes

Thank you! This saved me a lot of time figuring it out.

I think we can even generalise it further using n = (t + 1)/2 so that it works for any number of side-by-side charts. I’ve only tested it with the example in the exercise though.

Hello, a newbie here i just wanted to know how this code is giving x values at the point 0,2,4… etc for the first bar set and 0.8,2.8,4.8… for the second bar set. I think the w value should be equals 0.4 because then the blue bar would start at the 0 value and the orange bar will start at the 0.8 value.

Hello, i’ve been struggling to understand the logic behind this concept (hope i’m not the only one here) as I like to understand how the code works and not so much to remember or copy-paste the formula.

I tried to simplify the code hoping it could help me understand how it works and I think I’ve got it now. I will post it here hoping someone can give me feedback to check if i’m doing something wrong (and if i’m right to help those that struggle to understand like I did):

store1_x = [X*2 for X in range(6)]

plt.bar(store1_x, sales1)

# Here's the basic formula for the first set of bars (blue ones). 
# As I understand, you want a list from 0 to 5 ( range(6) ) because you need to plot 6 blue bars. 
# X is every element of that list, and it's being multiplied by 2 to separate the blue bars between each other to make room for the orange bars.


store2_x = [X*2 + 1 for X in range(6)]

plt.bar(store2_x, sales2)

# This is the code for the orange bars, it's the same as above, but adding 1. 
# This places the orange bar one space to the right of the preceding blue bar. 
# In the exercise this was originally 0.8, which places the blue and orange bars next to each other.
# A width of 0.8 is actually better to understand the data, but I changed it as it helped me to visualize how the code works.

So basically you’re creating two lists of positions:

[0, 2, 4, 6, 8, 10]
for the blue bars

and

[0+1, 2+1, 4+1, 6+1, 8+1, 10+1]
or
[1, 3, 5, 7, 9, 11]
for the orange bars

NOTE: I know this code positions the ticks in the X axis differently than the initial code, but I think this doesn’t matter when you’re working with string type labels (such as ‘months’, or in this case ‘drinks’) (?)

I hope someone can tell me if i’m understanding this correctly and help others that like to understand how their code works.

Cheers! :beer:

Thank you for sharing!

That’s right, this formula should work with any number of bars:

x_ticks = [t*element + (w * (t + 1) * .5) for element in range(d)]

Took me some fiddling, but it was a nice challenge! :slight_smile: Not sure if it’s the most elegant solution, though!

'''
The formula given by Codecademy worked for me:
plt.bar([x * num_of_datasets + bar_width * num_of_dataset_to_plot \
    for x in range(len(list_of_x_values))], y_values)

Where:
x * num_of_datasets --> sets the initial x value for each element in list_of_x_values
+ bar_width * num_of_dataset_to_plot --> shifts the x value to match the dataset bar location

In example:
list_of_x_values = [0, 1, 2]
DATASET 1: plt.bar([x*2 +0.8*1 for x in range(len(list_of_x_values))], y_values)
DATASET 2: plt.bar([x*2 +0.8*2 for x in range(len(list_of_x_values))], y_values)
will produce the following plot:
DATASET 1:[0.8, 2.8, 4.8]
DATASET 2:[1.6, 3.6, 5.6]
these will be the default values for the _xticks! 
Remember that by default the ticks are aligned to the center of the bar. 

The same formula works for the _xticks:
ax.set_xticks([x*2 +1.2 for x in range(len(list_of_x_values))])
Where:
I'm copying DATASET 1 values but because the tick is at the center of the DATASET 1 bar,
I need to add 1/2 of width (0.8 + 0.4) to shift the tick forward.
Now it sits between both bars.

If you have an odd number of datasets, just pick the middle values for _xticks.
If you have large even dataset numbers, pick the middle value and add 1/2 of width.
'''

I’m trying to add labels for the x-ticks in this exercise. From try and error, I found that this comprehensive list [telement + wn/1.35 for element in range(d)] will center the tick marks in the middle of each bar-set instead of using the same than store2_x, as I thought at the beginning. Can someone explain to me what’s the logic? Thanks

This is what annoys me a lot about CodeCademy. Why do you make me learn this the hard way, when I can easily create this same graph in Seaborn with just one line of code!?
WHY!?
This is a waste of everyone’s time. I am here to learn how to do data science in the most efficient way using python, not to learn the inner workings of a coding language or the inner workings of different libraries. In the future, you should just consider teaching people how to do things the most efficient way and skip unnecessary nonsense like this.