1

I'm trying to plot a bar graph, and I have multiple lists for xaxisn (n from 1 to 5) and yaxisn (1 to 5). The values in each respective xaxisn were originally mapped to the values in yaxisn in a dictionary, and they are the same from 1 to 5 but in different order. For example

dict1 = {'a': 80, 'c': 30, 'e': 52, 'b': 12, 'd': 67}
dict2 = {'c': 47, 'a': 73, 'e': 32, 'd': 35, 'b': 40}

So I created a list containing all the nominal values for x and tried to plot everything together with

xaxis = ['a', 'b', 'c', 'd', 'e']
yaxis1 = dict1.values()
xaxis1 = dict1.keys()
yaxis2 = dict2.values()
xaxis2 = dict2.keys()
plt.bar(xaxis1,yaxis1)
plt.bar(xaxis2,yaxis2)
plt.xticks(range(len(xaxis)),xaxis)

but I've noticed that despite being mapped together, the y values in the graph aren't aligned to the right x. So instead of showing, in order the frequencies for xaxis, they keep the same order as in the dictionary. I have tried to change the last line of code into

plt.xticks(range(len(xaxis)),xaxis1)
plt.xticks(range(len(xaxis)),xaxis2)

but again, with multiple variables, one overwrites the previous one. Do I need to order all the dictionaries the same way to plot them, or is there another way to do it without having to redo all my codes?

5
  • You could always plot sorted versions of your dictionaries dict1_sorted = {k: v for k, v in sorted(dict1.items(), key=lambda item: item[1])}
    – Taxel
    Commented Jan 16, 2020 at 2:51
  • @Taxel based on what does it sort it? Commented Jan 16, 2020 at 2:54
  • @Taxel the actual keys that I have do not really have an order, does it work with them too? Commented Jan 16, 2020 at 2:55
  • It should sort them lexically, so "a", "asd", "b"... - as long as your keys are strings, this should work fine.
    – Taxel
    Commented Jan 16, 2020 at 2:56
  • The sort routines are guaranteed to use __lt__() when making comparisons between two objects - if your key objects support less-than comparison you can sort dict1.items() and dict2.items() to ensure order.
    – wwii
    Commented Jan 16, 2020 at 3:21

1 Answer 1

1

You can ensure that the order for the two y axes are the same by using the keys of one dict to extract the values from both. Here is one way to do it.

import operator

dict1 = {'a': 80, 'c': 30, 'e': 52, 'b': 12, 'd': 67}
dict2 = {'c': 47, 'a': 73, 'e': 32, 'd': 35, 'b': 40}

xs = dict1.keys()
f = operator.itemgetter(*xs)
y1 = f(dict1)
y2 = f(dict2)

>>> xs
dict_keys(['a', 'c', 'e', 'b', 'd'])
>>> y1
(80, 30, 52, 12, 67)
>>> y2
(73, 47, 32, 40, 35)
>>>

Then use xs for all the plotting.

plt.bar(xs,y1)
plt.bar(xs,y2)
plt.xticks(range(len(xs)),xs)
plt.show()
plt.close()

operator.itemgetter will get each item it is instantiated with in the order they were given. Similar to these list comprehensions.

>>> [dict1[k] for k in xs]
[80, 30, 52, 12, 67]
>>> [dict2[k] for k in xs]
[73, 47, 32, 40, 35]
>>> 
6
  • Just to double check, could you briefly explain the function of the package operator? As it's my first time seeing it Commented Jan 16, 2020 at 4:12
  • From what I understand, f is a way to reorder the dictionaries based on key order. What I don't get is y1=f(dict1) Does this only change the order or also specify that y1 only cares for the values? Commented Jan 16, 2020 at 4:16
  • @jfilenxd845 - see edit. It doesn't reorder the dictionaries, it retrieves the values in a specific order.
    – wwii
    Commented Jan 16, 2020 at 14:45
  • So is saying y1=f(dict1) or y1=f(dict1).values() the same in this case? Commented Jan 16, 2020 at 16:42
  • Also, I have just noticed that one of the dictionaries is missing a key, I've tried to create a for loop to avoid getting an error when this happens but it's not working. What would you do? Commented Jan 16, 2020 at 17:00

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.