3

I am trying to make a stackplot from a dictionary where the value is a list of floats between 0 and 1 and the index of the value in the list is the time (t1, t2, ...tn) of measurement. All keys have the same number of values. For example:

a = {1:[0.3,0.5,0.7], 2:[0.4,0.6,0.8], 5:[0.1,0.15,0.20]}

so that at t2: a[1] = 0.5, a[2] = 0.6, and a[5] = 0.15, and so on at the other indices of the list of values.

I'm going for a stackplot like the one here with the indices of the value list on the x-axis and the value of a[i] at that index on the y-axis , but can't figure out how to adapt that code or the matplotlib example to a dictionary.

Python version: 3.4

Error (for both my data and toy data set): TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

Suggestions?

DreadPirateShawn
  • 8,164
  • 4
  • 49
  • 71
bradi
  • 97
  • 7
  • The syntax of your dictionary is invalid. – BrenBarn Jul 31 '15 at 19:21
  • that is an incorrect dictionary syntax. a dictionary is written like `a = {1:[0.3,0.5,0.7], 2:[0.4,0.6,0.8]}` – awbemauler Jul 31 '15 at 19:22
  • Noted, that was a typo in the example. Not a problem I encountered in my true dictionary. – bradi Jul 31 '15 at 19:24
  • Am I right in assuming that you don't actually need the keys of `a`? – j-i-l Jul 31 '15 at 19:48
  • @jojo Right -- the keys of a are just identifiers, so the only time I'd use them is in building the legend. – bradi Jul 31 '15 at 19:50
  • I'm getting the TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''. – bradi Jul 31 '15 at 19:58
  • @jojo Both -- and I'm using Python 3.4. – bradi Jul 31 '15 at 20:07
  • In this case try my answer with `fnx = lambda : np.random.randint(5, 50, 10).values.astype(np.float64)` which enforces the elements to be actual floating point numbers. – j-i-l Jul 31 '15 at 20:09
  • @jojo then I get AttributeError: 'numpy.ndarray' object has no attribute 'values' – bradi Jul 31 '15 at 20:21

2 Answers2

3

UPDATE - The error you are getting is because matplotlib is somehow not happy with the view you are getting from dict.values(). Note that this is only a problem of python 3.x as for python 2.x dict.values() returns a list. You can simply avoid this problem by converting the view into a normal list, so list(dict.values()).

Here is the matplotlib example using a dict, working for both python 2.x and 3.x:

import numpy as np
from matplotlib import pyplot as plt

fnx = lambda : np.random.randint(5, 50, 10).astype(np.float64)
d = {i: v for i, v in enumerate(np.row_stack((fnx(), fnx(), fnx())))}
# d looks basically like your a
x = range(len(d[0]))
y = list(d.values()) # d.values() returns a view in python 3.x
fig, ax = plt.subplots()
ax.stackplot(x, y)
plt.show()
j-i-l
  • 10,281
  • 3
  • 53
  • 70
  • range() replaced xrange() in Python 3+ – bradi Jul 31 '15 at 20:34
  • Even once I remove .values, I still get the TypeError. Would it matter that some of the decimal numbers I use are particularly long? – bradi Jul 31 '15 at 20:35
  • @bradi note that Decimal type [is not supported](http://matplotlib.1069221.n5.nabble.com/type-error-with-python-3-2-and-version-1-1-1-of-matplotlib-numpy-error-td38784.html) so you should be fine if you convert your dictionary `a` to contain only floats. – j-i-l Jul 31 '15 at 20:39
  • @bradi to convert all the entries in `a` to floats: `a = {i: map(lambda x: float(x), a[i]) for i in a}` – j-i-l Jul 31 '15 at 20:45
  • @bradi The issue is that dict.values() is a [view](https://docs.python.org/3/library/stdtypes.html#dict-views) in python 3.x. This is what was causing the error. `y = list(d.values())` will get you there (finally :P). – j-i-l Jul 31 '15 at 21:12
0

It's not entirely clear what you want to achieve, but if I understood you, this should work:

import matplotlib.pyplot as plt
a = {1:[0.3,0.5,0.7], 2:[0.4,0.6,0.8], 5:[0.1,0.15,0.20]}
plt.stackplot(a.keys(),a.values())

enter image description here

Diziet Asahi
  • 38,379
  • 7
  • 60
  • 75