0

I am currently learning SciPy and I want to play a little bit with pylab and matplotlib so as an exercise I tried to visualize Reddit's hot function.

Of course this code is not working, and I can't really figure out how to google what I want.

from pylab import *
import numpy as np

def f(t,v):
    y = lambda a : 1 if a > 0 else (-1 if a < 0 else 0)

    z = lambda a : log10(abs(a)) if abs(a) >= 1 else log10(1)

    return map(z,v)*map(y,v) + t

n = 256
x = np.linspace(0,100,n)
y = np.linspace(-50,+50,n)
X,Y = np.meshgrid(x,y)

contourf(X, Y, f(X,Y), 15, alpha=.75, cmap='jet')
C = contour(X, Y, f(X,Y), 15, colors='black', linewidth=.5)
show()

EDIT: By not working it means that it is giving me the following error message:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-33-a1d2f439ebda> in <module>()
     13 X,Y = np.meshgrid(x,y)
     14 
---> 15 contourf(X, Y, f(X,Y), 15, alpha=.75, cmap='jet')
     16 C = contour(X, Y, f(X,Y), 15, colors='black', linewidth=.5)
     17 show()

<ipython-input-33-a1d2f439ebda> in f(t, v)
      6     z = lambda a : log10(abs(a)) if abs(a) >= 1 else log10(1)
      7 
----> 8     return map(z,v)*map(y,v) + t
      9 
     10 n = 256

<ipython-input-33-a1d2f439ebda> in <lambda>(a)
      4     y = lambda a : 1 if a > 0 else (-1 if a < 0 else 0)
      5 
----> 6     z = lambda a : log10(abs(a)) if abs(a) >= 1 else log10(1)
      7 
      8     return map(z,v)*map(y,v) + t

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
YXD
  • 31,741
  • 15
  • 75
  • 115
firas
  • 1,463
  • 4
  • 19
  • 42
  • Don't know the hot function, what "not working" looks like, what working looks like, or what your question is. Voting to close. – duffymo Mar 25 '15 at 16:58
  • I edited the post and showed what's not working. – firas Mar 25 '15 at 17:22
  • 1
    This looks important: "ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()" – duffymo Mar 25 '15 at 20:27
  • Yes, but I don't understand the error and when I look it up I get solutions to a problem I don't have. I am trying to apply a function on an array using `map` and it's throwing me this error. – firas Mar 25 '15 at 20:30

1 Answers1

2

The error is from if a > 0, as the error says the truth value of a, which will be a NumPy array is ambiguous.

Why is a a NumPy array rather than a single entry? Python's map does not iterate over each element of the array, it will iterate over one dimension only and your input is multidimensional:

>>> a = np.arange(12).reshape(3, 4)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> f = lambda x : x
>>> map(f, a)
[array([0, 1, 2, 3]), array([4, 5, 6, 7]), array([ 8,  9, 10, 11])]

You could use np.vectorize instead of map, which will work as you want, but you should really be using vectorized NumPy functions on NumPy arrays, where the iteration will be handled by fast native code. Here's how to write your code in this way:

import numpy as np
from pylab import *

def f(t,v):
    # reproduce "y" with vectorized functions
    temp_a = np.sign(v)

    # reproduce "z" with vectorized functions
    temp_b = np.log10(np.maximum(np.abs(v), 1.0))

    # could also do something like
    # abs_v = np.abs(v)
    # temp_b = np.where(abs_v >= 1, np.log10(abs_v), np.log10(1))

    return temp_a * temp_b + t

n = 256
x = np.linspace(0,100,n)
y = np.linspace(-50,+50,n)
X,Y = np.meshgrid(x,y)

contourf(X, Y, f(X,Y), 15, alpha=.75, cmap='jet')
C = contour(X, Y, f(X,Y), 15, colors='black', linewidth=.5)
show()

Recommended reading:

I would also suggest not using pylab but importing the modules you need explicitly. e.g. here you would do import matplotlib.pyplot as plt and use plt.contour and plt.show(). See Pylab discussion here and here.

Community
  • 1
  • 1
YXD
  • 31,741
  • 15
  • 75
  • 115
  • Thanks a lot. I am still getting my head around this a little bit. Could you please correct a typo in the code? (temp_c should really be temp_b) – firas Mar 27 '15 at 10:37