J'ai des problèmes pour tracer une deuxième colonne d'une trame de données pandas sur un axe y twinx. Je pense que c'est peut-être parce que la deuxième colonne problématique contient des valeurs NaN. Les valeurs de NaN sont là parce qu'il n'y avait que des données disponibles tous les 10 ans, bien que pour la première colonne, il y avait des données disponibles chaque année. Ils ont été générés en utilisant np.nan que j'ai inclus à la fin pour plus de clarté.

L'intuition ici est de tracer les deux séries sur le même axe x pour montrer comment elles évoluent dans le temps.

Voici mon code et mon dataframe:

import pandas as pd
import numpy as np
import matplotlib as plt
import matplotlib.pyplot as plt

list1 = ['1297606', '1300760', '1303980', '1268987', '1333521', '1328570', 
         '1328112', '1353671', '1371285', '1396658', '1429247', '1388937', 
         '1359145', '1330414', '1267415', '1210883', '1221585', '1186039', 
         '884273', '861789', '857475', '853485', '854122', '848163', '839226', 
         '820151', '852385', '827609', '825564', '789217', '765651']

list1a = [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 
          1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 
          2004, 2005, 2006, 2007, 2008, 2009, 2010]

list3b = [121800016.0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, 
          145279588.0, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, 
          160515434.5, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, 
          168140487.0]

d = {'Year': list1a,'Abortions per Year': list1, 
     'Affiliation with Religious Institutions': list3b}
newdf = pd.DataFrame(data=d)

newdf.set_index('Year',inplace=True)

fig, ax1 = plt.subplots(figsize=(20,5))

y2min = min(newdf['Affiliation with Religious Institutions'])
y2max = max(newdf['Affiliation with Religious Institutions'])
ax1.plot(newdf['Abortions per Year'])
#ax1.set_xticks(newdf.index)
ax1b = ax1.twinx()
ax1b.set_ylim(y2min*0.8,y2max*1.2)
ax1b.plot(newdf['Affiliation with Religious Institutions'])
plt.show()

Je me retrouve avec un graphique qui ne montre pas la deuxième intrigue. (Quand j'ai changé le deuxième tracé pour avoir des valeurs numériques pour chaque année, il le trace). Voici le deuxième tracé (avec des valeurs NaN) - ignoré:

enter image description here

Reconnaissant pour tout conseil.

* comment les valeurs np.nan ont été générées pour la deuxième colonne: j'ai parcouru la colonne d'index et pour chaque année sans données, j'ai renvoyé np.nan à la liste, qui a ensuite été transformée en colonne.

for i in range(len(list1a)):
    if list1a[i] in list3a:
        var = list2[j]
        list3b.append(var)

        j+=1
    else:
        var = np.nan
        list3b.append(var)
0
ZakS 23 mai 2018 à 15:19

4 réponses

Meilleure réponse

Deux choses. Vous devez convertir la colonne Abortions per Year en un type numérique pour le traçage, au moins pour les données que vous avez fournies au format str; deuxièmement, vous pouvez tracer Affiliation with Religious Institutions sous forme de ligne en supprimant les valeurs nan avant de tracer.

ax1.plot(newdf['Abortions per Year'].astype(int))

...

ax1b.plot(newdf['Affiliation with Religious Institutions'].dropna())
2
James 23 mai 2018 à 12:40

Vous pouvez utiliser des méthodes pandas DataFrame pour la plupart des choses que vous faites. Ces deux lignes résoudront tous vos problèmes:

newdf = newdf.astype(float)
newdf = newdf.interpolate(method='linear')

Ainsi, votre code de traçage ressemblera à ceci:

fig, ax1 = plt.subplots(figsize=(20,5))

newdf = newdf.astype(float)
newdf = newdf.interpolate(method='linear')
y2min = newdf['Affiliation with Religious Institutions'].min()
y2max = newdf['Affiliation with Religious Institutions'].max()
newdf['Abortions per Year'].plot.line(ax=ax1)
#ax1.set_xticks(newdf.index)
ax1b = ax1.twinx()
ax1b.set_ylim(y2min*0.8,y2max*1.2)
newdf['Affiliation with Religious Institutions'].plot.line(ax=ax1b)
plt.show()

L'utilisation des méthodes pandas pour tracer un DataFrame n'est qu'une recommandation. Mais vous pouvez également utiliser votre code matplotlib, car pandas utilise matplotlib comme backend de traçage

Les deux lignes que j'ai ajoutées font ce qui suit:
Votre colonne Abortions per Year est de dtype object. Vous devez le convertir en un type numérique avec:

newdf = newdf.astype(float)

En fait, les NaN - valeurs ne sont pas ignorées, mais pas affichées car ce sont des valeurs uniques. Ainsi, vous pouvez ajouter un marker au deuxième tracé. Si vous souhaitez afficher une ligne pour le deuxième tracé, vous devez interpoler les valeurs avec:

newdf = newdf.interpolate(method='linear')

Les marqueurs peuvent être supprimés si l'interpolation est effectuée.

1
Scotty1- 23 mai 2018 à 12:58

Une chose fondamentale qui ne va pas ici est que vous tracez un point sous forme de ligne.

List3b = [121800016.0, nan, nan ....... Va d'un point à rien.

Si vous changez le deuxième nan en valeur: list3b = [121800016.0, 121800016.0, nan, ..... alors vous verrez un résultat. entrez la description de l'image ici

Vous devriez peut-être tracer ces valeurs sous forme de barres ou de points de dispersion.

0
GeorgeLPerkins 23 mai 2018 à 12:37

entrez la description de l'image ici Je comprends maintenant. Pour y parvenir avec votre code existant, il vous suffit d'utiliser le Pandas Forwardfill.

Juste après

newdf.set_index('Year',inplace=True)

Mettez juste

newdf.fillna(method='ffill', inplace=True)
2
GeorgeLPerkins 23 mai 2018 à 13:01