J'essaie de créer un nuage de points de base basé sur un cadre de données Pandas. Mais lorsque j'appelle la routine scatter, l'erreur "TypeError: promotion de type non valide" est générée. Un exemple de code permettant de reproduire le problème est présenté ci-dessous:
t1 = pd.to_datetime('2015-11-01 00:00:00')
t2 = pd.to_datetime('2015-11-02 00:00:00')
Time = pd.Series([t1, t2])
r = pd.Series([-1, 1])
df = pd.DataFrame({'Time': Time, 'Value': r})
print(df)
print(type(df.Time))
print(type(df.Time[0]))
fig = plt.figure(figsize=(x_size,y_size))
ax = fig.add_subplot(111)
ax.scatter(df.Time, y=df.Value, marker='o')
La sortie qui en résulte est
Time Value
0 2015-11-01 -1
1 2015-11-02 1
<class 'pandas.core.series.Series'>
<class 'pandas.tslib.Timestamp'>
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-285-f4ed0443bf4d> in <module>()
15 fig = plt.figure(figsize=(x_size,y_size))
16 ax = fig.add_subplot(111)
---> 17 ax.scatter(df.Time, y=df.Value, marker='o')
C:\Anaconda3\lib\site-packages\matplotlib\axes\_axes.py in scatter(self, x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, verts, **kwargs)
3635 edgecolors = 'face'
3636
-> 3637 offsets = np.dstack((x, y))
3638
3639 collection = mcoll.PathCollection(
C:\Anaconda3\lib\site-packages\numpy\lib\shape_base.py in dstack(tup)
365
366 """
--> 367 return _nx.concatenate([atleast_3d(_m) for _m in tup], 2)
368
369 def _replace_zero_by_x_arrays(sub_arys):
TypeError: invalid type promotion
En cherchant, j'ai trouvé un article similaire Pandas Series TypeError et ValueError avec datetime , ce qui suggère que l'erreur est due à la présence de plusieurs types de données dans la série. Mais cela ne semble pas être le problème dans mon exemple, comme en témoigne le type d'informations que j'imprime.
Notez que si j’arrête d’utiliser des objets datas de pandas et que je fais de la "Time" un nombre à la place, cela fonctionne très bien, par exemple.
t1 = 1.1 #
t2 = 1.2
Time = pd.Series([t1, t2])
r = pd.Series([-1, 1])
df = pd.DataFrame({'Time': Time, 'Value': r})
print(df)
print(type(df.Time))
print(type(df.Time[0]))
fig = plt.figure(figsize=(x_size,y_size))
ax = fig.add_subplot(111)
ax.scatter(df.Time, y=df.Value, marker='o')
avec sortie
Time Value
0 1.1 -1
1 1.2 1
<class 'pandas.core.series.Series'>
<class 'numpy.float64'>
et le graphique a l'air bien. Je ne sais pas pourquoi l'utilisation d'une date/heure est à l'origine de l'erreur de promotion de type non valide? J'utilise Python 3.4.3 et Pandas 0.16.2.
Merci @martinvseticka. Je pense que votre évaluation est correcte sur la base du code numpy que vous m'avez indiqué. J'ai pu simplifier un peu plus vos réglages (et ajouté un troisième point d'échantillon) pour obtenir
t1 = pd.to_datetime('2015-11-01 00:00:00')
t2 = pd.to_datetime('2015-11-02 00:00:00')
t3 = pd.to_datetime('2015-11-03 00:00:00')
Time = pd.Series([t1, t2, t3])
r = pd.Series([-1, 1, 0.5])
df = pd.DataFrame({'Time': Time, 'Value': r})
fig = plt.figure(figsize=(x_size,y_size))
ax = fig.add_subplot(111)
ax.plot_date(x=df.Time, y=df.Value, marker='o')
La clé semble appeler "plot_date" plutôt que "plot". Cela semble informer mapplotlib de ne pas essayer de concaténer les tableaux.
Il y a une autre façon de supprimer les utilisations de la série. Il suffit d'utiliser la liste pour le temps.
t1 = pd.to_datetime('2015-11-01 00:00:00')
t2 = pd.to_datetime('2015-11-02 00:00:00')
Time = pd.Series([t1, t2])
r = pd.Series([-1, 1])
df = pd.DataFrame({'Time': Time, 'Value': r})
print(df)
print(type(df.Time))
print(type(df.Time[0]))
x_size = 800
y_size = 600
fig = plt.figure(figsize=(x_size,y_size))
ax = fig.add_subplot(111)
ax.scatter(list(df.Time.values), list(df.Value.values), marker='o')
Est-ce ce que vous recherchez?
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as dates
t1 = pd.to_datetime('2015-11-01 00:00:00')
t2 = pd.to_datetime('2015-11-02 00:00:00')
idx = pd.Series([t1, t2])
s = pd.Series([-1, 1], index=idx)
fig, ax = plt.subplots()
ax.plot_date(idx, s, 'v-')
plt.tight_layout()
plt.show()
Je suis nouveau sur Python alors j'espère que je ne me trompe pas. Fondamentalement, j'ai essayé d'adapter votre exemple en fonction de https://stackoverflow.com/a/13674286/99256 .
Le problème avec votre script est que numpy
tente de concaténer les séries df.Time
et df.Value
et qu'il ne peut pas trouver un type approprié pour le nouveau tableau car un tableau est numérique et le second est composé d'instances Timestamp
.
Les graphes scatter
ont des propriétés qui ne peuvent pas être simulées dans plot
ou plot_date
(en tant que possibilité de tracer des marqueurs avec des tailles variables).
La conversion de la série temporelle de type: pandas.tslib.Timestamp
en une liste de type: datetime.datetime
avant de tracer le diagramme de dispersion a fonctionné à mon avantage:
times = [d.to_pydatetime() for d in df.Time]]
ax.scatter(times, y=df.Value, marker='o')
Vous pouvez aussi faire quelque chose comme ça:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import datetime
df = pd.DataFrame({"Time":["2015-11-01 00:00:00", "2015-11-02 00:00:00"], "value":[ 1, -1]})
df['Time'] = pd.to_datetime(df['Time'])
fig, ax = plt.subplots()
ax.scatter(np.arange(len(df['Time'])), df['value'], marker='o')
ax.xaxis.set_ticks(np.arange(len(df['Time'])))
ax.xaxis.set_ticklabels(df['Time'], rotation=90)
plt.xlabel("Time")
plt.ylabel("value")
plt.show()
J'ai changé le type de colonne datetime en chaîne dans fly:
plt.scatter(df['Date'].astype('str'), df['Category'], s=df['count'])
et le nuage de points fonctionne . Cordialement