4

I need to plot a histogram with the following dictionary

x = {5:289, 8:341, 1:1565, 4:655, 2:1337, 9:226, 7:399, 3:967, 6:405}

I need first keys be ordered from 1 to 9. Then the values will be plotted in the histogram, showing a maximum probability of 1.0. I have tried the following (plus other stuff).

import matplotlib.pyplot as plt
import numpy as np

plt.hist(x.keys(), x.values(), color='g', label = "Real distribution")
plt.show()

Or

plt.hist (x, bins = np.arange(9), color = 'g', label = "Real distribution")
plt.show()

Or

fsn_count_ = sorted(fsn_count)

plt.hist (fsn_count_, bins = np.arange(9), color = 'b', label = "Real distribution")
plt.plot ([0] + bf, color = 'g', label = "Benford Model")
plt.xlabel ('Significant number')
plt.ylabel ('Percentage')
plt.xlim (1,9)
plt.ylim (0,1)
plt.legend (bbox_to_anchor = (1, 1), loc="upper right", borderaxespad=0.)
plt.savefig (country_ + '.png')
plt.show ()
plt.clf ()

distribution_sum = sum(bf)
print('The sum of percentage distribution is:', distribution_sum)
Daniel
  • 218
  • 1
  • 2
  • 9
  • Note that dictionaries aren't designed for ordered keys. `x.keys()` _will_ give you all the keys of `x`, but not necessarily in the order it did the last time you called it. – Jakob Lovern Dec 08 '17 at 00:32
  • So, what would be then a good way of storing this information? I do need to know how many times the number five, six... n, appers and then plot it. – Daniel Dec 08 '17 at 00:34
  • First, are you using python 3.x or python 2.x? – Jakob Lovern Dec 08 '17 at 00:35
  • I am using Python 3.x – Daniel Dec 08 '17 at 00:38
  • Nevermind, Ajax1234 beat me to the punch, and used a much more elegant solution than whatever it was I was gonna kluge together. – Jakob Lovern Dec 08 '17 at 00:40
  • You can try a bar plot like in this question ["Plot a histogram from a dictionary"](https://stackoverflow.com/questions/21195179/plot-a-histogram-from-a-dictionary) –  Dec 08 '17 at 00:40
  • @JakobLovern Please feel free to post your solution. – Ajax1234 Dec 08 '17 at 00:43
  • @Daniel How do you know what the probability is? Are you taking the key with the maximum value (1 in this case) to have a probability of 1? – DavidG Dec 08 '17 at 09:24
  • @DavidG I made a count from an original list were only numbers from 1 to 9 were available. These became the keys, whereas the quantity became the values. The sum of all values equal to 100% (5584), so the probability of 5 will be 289/5584. – Daniel Dec 09 '17 at 15:27

3 Answers3

6

From your comment, it seems that a bar chart would be a better way to display the data.

The probability can be found by dividing the values of the dictionary by the sum of the values:

import matplotlib.pyplot as plt
import numpy as np

x = {5:289, 8:341, 1:1565, 4:655, 2:1337, 9:226, 7:399, 3:967, 6:405}

keys = x.keys()
vals = x.values()

plt.bar(keys, np.divide(list(vals), sum(vals)), label="Real distribution")

plt.ylim(0,1)
plt.ylabel ('Percentage')
plt.xlabel ('Significant number')
plt.xticks(list(keys))
plt.legend (bbox_to_anchor=(1, 1), loc="upper right", borderaxespad=0.)

plt.show()

enter image description here

DavidG
  • 24,279
  • 14
  • 89
  • 82
2

Sort your data before plotting:

import matplotlib.pyplot as plt
import numpy as np
x = {5:289, 8:341, 1:1565, 4:655, 2:1337, 9:226, 7:399, 3:967, 6:405}
new_x = sorted(x.items(), key=lambda x:x[0])
plt.hist([i[-1] for i in new_x], normed=True, bins=len(new_x), color='g', label = "Real distribution")
plt.show()

enter image description here

Ajax1234
  • 69,937
  • 8
  • 61
  • 102
-1

I'm sorry in advance for how terribly un-pythonic and weird my code is. I'm not too strong with mathplot or with numpy.

If you used the_keys = list(set(dict.keys())) to get a set of the keys (ordered, because it was a set. Like I said in comments, I'm doing some pretty ugly hacking here.) you can then do the_values = [x[i] for i in the_keys] to get a list representation of the dictionary ordered by keys. Then plot it with

plt.hist(the_keys, the_values, color='g', label = "Real distribution")
plt.show()
Jakob Lovern
  • 1,301
  • 7
  • 24