Matplotlib: TypeError: no se puede multiplicar la secuencia por un tipo no int 'numpy.float64'

Resuelto Sam asked hace 9 años • 2 respuestas

Estoy tratando de ajustar una línea lineal de mejor ajuste a mi gráfico matplotlib. Sigo recibiendo el error de que xey no tienen la misma primera dimensión. Pero ambos tienen longitudes de 15. ¿Qué estoy haciendo mal?

import matplotlib.pyplot as plt
from scipy import stats
import numpy as np

x = [0.46,0.59,0.68,0.99,0.39,0.31,1.09,0.77,0.72,0.49,0.55,0.62,0.58,0.88,0.78]
y = [0.315,0.383,0.452,0.650,0.279,0.215,0.727,0.512,0.478,0.335,0.365,0.424,0.390,0.585,0.511]
xerr = [0.01]*15
yerr = [0.001]*15

plt.rc('font', family='serif', size=13)
m, b = np.polyfit(x, y, 1)
plt.plot(x,y,'s',color='#0066FF')
plt.plot(x, m*x + b, 'r-') #BREAKS ON THIS LINE
plt.errorbar(x,y,xerr=xerr,yerr=0,linestyle="None",color='black')
plt.xlabel('$\Delta t$ $(s)$',fontsize=20)
plt.ylabel('$\Delta p$ $(hPa)$',fontsize=20)
plt.autoscale(enable=True, axis=u'both', tight=False)
plt.grid(False)
plt.xlim(0.2,1.2)
plt.ylim(0,0.8)
plt.show()

Error

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_34116/1820029981.py in <module>
      7 m, b = np.polyfit(x, y, 1)
      8 plt.plot(x,y,'s',color='#0066FF')
----> 9 plt.plot(x, m*x + b, 'r-') #BREAKS ON THIS LINE
     10 plt.errorbar(x,y,xerr=xerr,yerr=0,linestyle="None",color='black')
     11 plt.xlabel('$\Delta t$ $(s)$',fontsize=20)

TypeError: can't multiply sequence by non-int of type 'numpy.float64'
Sam avatar Nov 01 '14 21:11 Sam
Aceptado

Deberías crear xmatrices ynumerosas, no listas:

x = np.array([0.46,0.59,0.68,0.99,0.39,0.31,1.09,
              0.77,0.72,0.49,0.55,0.62,0.58,0.88,0.78])
y = np.array([0.315,0.383,0.452,0.650,0.279,0.215,0.727,0.512,
              0.478,0.335,0.365,0.424,0.390,0.585,0.511])

Con este cambio, produce la trama esperada. Si son listas, m * xno producirá el resultado esperado, sino una lista vacía. Tenga en cuenta que mes un numpy.float64Python escalar, no un estándar float.

De hecho, considero que este comportamiento es un poco dudoso por parte de Numpy. En Python normal, multiplicar una lista por un número entero simplemente repite la lista:

In [42]: 2 * [1, 2, 3]
Out[42]: [1, 2, 3, 1, 2, 3]

mientras que multiplicar una lista con un flotante da un error (como creo que debería):

In [43]: 1.5 * [1, 2, 3]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-43-d710bb467cdd> in <module>()
----> 1 1.5 * [1, 2, 3]
TypeError: can't multiply sequence by non-int of type 'float'

Lo extraño es que multiplicar una lista de Python con un escalar de Numpy aparentemente funciona:

In [45]: np.float64(0.5) * [1, 2, 3]
Out[45]: []

In [46]: np.float64(1.5) * [1, 2, 3]
Out[46]: [1, 2, 3]

In [47]: np.float64(2.5) * [1, 2, 3]
Out[47]: [1, 2, 3, 1, 2, 3]

Entonces parece que el float se trunca a un int, después de lo cual se obtiene el comportamiento estándar de Python de repetir la lista, lo cual es un comportamiento bastante inesperado. Lo mejor hubiera sido generar un error (para que usted mismo hubiera detectado el problema en lugar de tener que hacer su pregunta en Stackoverflow) o simplemente mostrar la multiplicación de elementos esperada (en la que su código simplemente habría funcionado) . Curiosamente, la suma entre una lista y un escalar Numpy funciona:

In [69]: np.float64(0.123) + [1, 2, 3]
Out[69]: array([ 1.123,  2.123,  3.123])
Bas Swinckels avatar Nov 01 '2014 15:11 Bas Swinckels

¡Cambiar tus listas a numpymatrices hará el trabajo!

import matplotlib.pyplot as plt
from scipy import stats
import numpy as np 

x = np.array([0.46,0.59,0.68,0.99,0.39,0.31,1.09,0.77,0.72,0.49,0.55,0.62,0.58,0.88,0.78]) # x is a numpy array now
y = np.array([0.315,0.383,0.452,0.650,0.279,0.215,0.727,0.512,0.478,0.335,0.365,0.424,0.390,0.585,0.511]) # y is a numpy array now
xerr = [0.01]*15
yerr = [0.001]*15

plt.rc('font', family='serif', size=13)
m, b = np.polyfit(x, y, 1)
plt.plot(x,y,'s',color='#0066FF')
plt.plot(x, m*x + b, 'r-') #BREAKS ON THIS LINE
plt.errorbar(x,y,xerr=xerr,yerr=0,linestyle="None",color='black')
plt.xlabel('$\Delta t$ $(s)$',fontsize=20)
plt.ylabel('$\Delta p$ $(hPa)$',fontsize=20)
plt.autoscale(enable=True, axis=u'both', tight=False)
plt.grid(False)
plt.xlim(0.2,1.2)
plt.ylim(0,0.8)
plt.show()

ingrese la descripción de la imagen aquí

Srivatsan avatar Nov 01 '2014 15:11 Srivatsan