Posts: 18
Threads: 2
Joined: Mar 2017
I have a large csv file. This file is read and a
Counter is returned every predefined amount of lines. As an Example:
counter = [Counter({(0, 1): 9, (1, 2): 8}), Counter({(1, 2): 99, (0, 1): 99}), Counter({(1, 2): 256, (0, 1): 189}), Counter({(1, 5): 473, (0, 1): 301})] This is the script i used.
import matplotlib.pyplot as plt
import numpy
from collections import Counter
counter = [Counter({(0, 1): 9, (1, 2): 8}), Counter({(1, 2): 99, (0, 1): 99}), Counter({(1, 2): 256, (0, 1): 189}), Counter({(1, 5): 473, (0, 1): 301})]
fig = plt.figure()
ax1 = fig.add_subplot(111)
N = len(counter)
ind = numpy.arange(N)
j = 0
while j in range(0, len(counter)):
a, i = 0, 0
frequencies = counter[j].values()
names = counter[j].keys()
while i in range(0, len(frequencies)):
if i == 0:
ax1.bar(ind, frequencies[i], label=names[i], width=0.25)
a = frequencies[i]
else:
ax1.bar(ind, frequencies[i], label=names[i], width=0.25, bottom=a)
a += frequencies[i]
i += 1
j += 1
labels = ["%s to %s" % (200, 202)]
ax1.set_xticks(numpy.arange(N))
ax1.set_xticklabels(labels)
ax1.set_ylabel("Frequency")
ax1.set_xlabel("Material Contact")
ax1.legend()
plt. show() However, it returns as error message:
Quote:ValueError: incompatible sizes: argument 'height' must be length 4 or scalar
To overcome this, i change the ind to ind[j], but ended up wit ha lot of colors. And these colors do not relate to their respective bins.
Posts: 331
Threads: 2
Joined: Feb 2017
Mar-31-2017, 09:18 AM
(This post was last modified: Mar-31-2017, 09:18 AM by zivoni.)
pyplot.bar needs heights with same length as left array (for vertically orientated barplot), so for your data with left = ind with length 4 you need frequency[i] to be array/list with length 4.
Its not clear what you want to plot, it seems that you are trying to plot much more plots than you have data for ... Perhaps you have there one more loop than its necessary (and maybe you need to "reshape" your list/counters)
You should use for to loop over a range instead of while. And when that range is used just to iterate over list or dictionary, you should iterate directly over list or dictionary. Examples:
Output: >>> for item in [1,2,3]:
... print(item)
...
1
2
3
>>> d = {'a':[1,2], 'b':[3,4]}
>>> for key, value in d.items():
... print(key, value)
...
a [1, 2]
b [3, 4]
>>> for idx, (key, value) in enumerate(d.items()): # if you need index position, use enumerate
... print(idx, key, value)
...
0 a [1, 2]
1 b [3, 4]
its python3, but with change of print it works with python2 too
Posts: 18
Threads: 2
Joined: Mar 2017
@ zivoni, thank you for that.
Quote:so for your data with left = ind with length 4 you need frequency[i] to be array/list with length 4
Thank you for that, however, it does not solve the problem. I have attached images, maybe this may make it clearer.
Current Results
[Image: Espc90.png]
Expected Result
This is the new code i wrote after your explanation above, the issue i think lies in it read the I'th value of the counter list list then the internal Counter Collection, but when it goes out to the next i'th value, it loose the track of which bin it is in.
import matplotlib.pyplot as plt
import numpy
from collections import Counter
counter = [Counter({(0, 1): 9, (1, 2): 8}), Counter({(1, 2): 99, (0, 1): 99}), Counter({(1, 2): 256, (0, 1): 189}), Counter({(1, 5): 473, (0, 1): 301})]
fig = plt.figure()
ax1 = fig.add_subplot(111)
for idx, bins in enumerate(counter):
stacker = 0
for names, frequencies in (bins.iteritems()):
if idx == 0:
ax1.bar(idx, frequencies, label=names, width=0.25)
stacker = frequencies
else:
ax1.bar(idx, frequencies, label=names, width=0.25, bottom=stacker)
stacker += frequencies
labels = ["%s to %s" % (200, 202)]
ax1.set_xticks(numpy.arange(idx))
ax1.set_xticklabels(labels)
ax1.set_ylabel("Frequency")
ax1.set_xlabel("Material Contact")
ax1.legend()
plt.suptitle("Time Window %s to %s" % (200, 202))
plt.savefig("histogram.png")
plt. show()
Posts: 331
Threads: 2
Joined: Feb 2017
Mar-31-2017, 06:45 PM
(This post was last modified: Mar-31-2017, 06:45 PM by zivoni.)
(Mar-31-2017, 04:56 PM)alicarlos13 Wrote: the issue i think lies in it read the I'th value of the counter list list then the internal Counter Collection, but when it goes out to the next i'th value, it loose the track of which bin it is in.
Indeed it does, it plots bars for entire serie, not "piecewise" one by one (technically you can do it by zero-filling remaining bins ...). That was what i meant by one more loop and likely need to reshape your data (but i wasnt sure what do you want).
You should have all data for (0, 1) in one serie/list, data for (1,2) in another and so on. Something like:
Output: {(0, 1): [9, 99, 189, 301], (1, 2): [8, 99, 256, 0], (1, 5): [0, 0, 0, 473]}
You just need to take your "keys/labels", and for each key construct list of values - for each Counter in your counter list check if key is in Counter and append either its value or zero. You dont need need to store it in dict, but you should have lists of values and its keys/labels. With dict you dont have fixed order, so if you want specific order of values, you need to sort keys somehow.
I quickly converted your data and plotted it without any effort to beautify it:
import matplotlib.pyplot as plt
import numpy as np
from collections import Counter
counter = [Counter({(0, 1): 9, (1, 2): 8}), Counter({(1, 2): 99, (0, 1): 99}),
Counter({(1, 2): 256, (0, 1): 189}), Counter({(1, 5): 473, (0, 1): 301})]
N = len(counter)
series = {}
for key in {key for keys in counter for key in keys}:
series[key] = [(0 if key not in item else item[key]) for item in counter]
fig, ax = plt.subplots()
bottom, x = np.zeros(N), range(N)
for key in series:
ax.bar(x, series[key], label=key, bottom=bottom)
bottom += np.array(series[key])
plt.legend()
plt.savefig('boo.png', dpi=200) [Image: aCwpGUT.png]
Posts: 18
Threads: 2
Joined: Mar 2017
Thank You  .
Guess i did not understand your previous post. Either that, or i can not get over the fact that to create a graph and i have to reassemble the Collections Counter again, because that to me (at least) defies the concept of the Counter in the first place  .
Again, Thank You.
Final Result
[Image: a70Z0N.png]
|