1

If I had a dictionary of words and their frequency in a string, for example:

{'hello': 3, 'how': 4, 'yes': 10, 'you': 11, 'days': 10, 'are': 20, 'ago': 11}

How could I make a bar graph out of this using matplotlib? I found a previous question which had a seemingly good solution, but it didn't work for me (python: plot a bar using matplotlib using a dictionary)

When I run

plt.bar(range(len(d)), d.values(), align="center")
plt.xticks(range(len(d)), d.keys())

I get the error

TypeError: 'dict_keys' object does not support indexing

I don't really see where I'm indexing my dictionary. It might be because in the question from which I got the code the x-values were also numbers? I'm not sure.

2 Answers 2

10

Try wrapping your d.keys() in a list() call:

plt.bar(range(len(d)), d.values(), align="center")
plt.xticks(range(len(d)), list(d.keys()))

In Python3, dict.keys() doesn't return the list of keys directly, but instead returns a generator that will give you the keys one at a time as you use it.

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

3 Comments

Worked perfectly, thank you! I'll keep in mind that's how dict.keys() works.
This isn't very relevant to my question, but is there any way I can automate the space between the bars so that all the words can fit on the x-axis (or maybe make the words go to a new line?)
@Howcan maybe you'd like to split the long words to multiple lines?
1

On " is there any way I can automate the space between the bars so that all the words can fit on the x-axis (or maybe make the words go to a new line?)"

I will split the long words to multiple lines, e.g., 'looooooooongWord' to 'looooo-\noooong-\nWord':

In [300]: d={'hello': 3, 'how': 4, 'yes': 10, 'you': 11, 'days': 10, 'are': 20, 'ago': 11, 'looooooooongWord': 10}
     ...: plt.bar(range(len(d)), d.values(), align="center")
     ...: plt.xticks(range(len(d)), [split_word(i) for i in d.keys()])

where split_word is defined as:

In [595]: def split_word(s):
     ...:     n=6
     ...:     return '-\n'.join(s[i:i+n] for i in range(0, len(s), n))
     ...: split_word('looooooooongWord')
Out[595]: 'looooo-\noooong-\nWord'

enter image description here

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.