11 votes

Affichez deux niveaux de x_ticklabels sur un dataframe pandas à index multiples

J'ai un dataframe à index multiples où l'index a été dérivé à partir de dates. Il comprend des valeurs d'année et de trimestre.

Ce que je veux réaliser est un graphique avec deux ensembles d'étiquettes d'axe des x. L'étiquette de la graduation mineure doit représenter les valeurs de trimestre (1 à 4) et les étiquettes de graduation majeure les valeurs d'année. Cependant, je ne veux pas afficher toutes les étiquettes d'année, seulement les années uniques pour chacun des quatre trimestres.

C'est facile à représenter dans un graphique Excel, voici un exemple de ce que j'essaie de reproduire. entrer la description de l'image ici

Voici un exemple de mon jeu de données.

serotype_df = pd.DataFrame({'13v': {(2002, 1): 5,
  (2002, 2): 9,
  (2002, 3): 23,
  (2002, 4): 11,
  (2003, 1): 1,
  (2003, 2): 12,
  (2003, 3): 22,
  (2003, 4): 15,
  (2004, 1): 10,
  (2004, 2): 11,
  (2004, 3): 30,
  (2004, 4): 11,
  (2005, 1): 9,
  (2005, 2): 20,
  (2005, 3): 20,
  (2005, 4): 7},
 '23v': {(2002, 1): 1,
  (2002, 2): 8,
  (2002, 3): 18,
  (2002, 4): 5,
  (2003, 1): 5,
  (2003, 2): 16,
  (2003, 3): 13,
  (2003, 4): 7,
  (2004, 1): 4,
  (2004, 2): 4,
  (2004, 3): 20,
  (2004, 4): 5,
  (2005, 1): 4,
  (2005, 2): 5,
  (2005, 3): 10,
  (2005, 4): 5},
 '7v': {(2002, 1): 30,
  (2002, 2): 75,
  (2002, 3): 148,
  (2002, 4): 68,
  (2003, 1): 26,
  (2003, 2): 75,
  (2003, 3): 147,
  (2003, 4): 67,
  (2004, 1): 32,
  (2004, 2): 84,
  (2004, 3): 151,
  (2004, 4): 62,
  (2005, 1): 21,
  (2005, 2): 49,
  (2005, 3): 81,
  (2005, 4): 26},
 'Non-typed': {(2002, 1): 1,
  (2002, 2): 2,
  (2002, 3): 4,
  (2002, 4): 4,
  (2003, 1): 3,
  (2003, 2): 5,
  (2003, 3): 9,
  (2003, 4): 8,
  (2004, 1): 1,
  (2004, 2): 4,
  (2004, 3): 6,
  (2004, 4): 4,
  (2005, 1): 4,
  (2005, 2): 10,
  (2005, 3): 7,
  (2005, 4): 11},
 'Non-vaccine': {(2002, 1): 2,
  (2002, 2): 7,
  (2002, 3): 10,
  (2002, 4): 6,
  (2003, 1): 4,
  (2003, 2): 5,
  (2003, 3): 13,
  (2003, 4): 8,
  (2004, 1): 2,
  (2004, 2): 4,
  (2004, 3): 19,
  (2004, 4): 8,
  (2005, 1): 4,
  (2005, 2): 3,
  (2005, 3): 15,
  (2005, 4): 5}})

J'ai essayé d'utiliser un code d'un exemple différent de SO. Voici le code que j'ai essayé.

import pandas as pd
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(14,8), dpi=200) 
ax = fig.add_subplot(111)
ax1 = ax.twiny()

serotype_df.plot(kind='bar', ax=ax, stacked='True');

trunc = lambda x: x.strip("()").split(" ")[1]
tl = [ trunc(t.get_text()) for t in ax.get_xticklabels()]
ax.set_xticklabels(tl,rotation=0);

serotype_df.plot(kind='bar', ax=ax1, stacked='True');

trunc0 = lambda x: x.strip("()").split(", ")[0]
tl = [ trunc0(t.get_text()) for t in ax1.get_xticklabels()]
ax1.set_xticklabels(tl);

J'ai les étiquettes de trimestre exactement là où je les veux. Je n'arrive juste pas à obtenir les valeurs d'année uniques.

Toute aide est grandement appréciée.

7voto

gyx-hh Points 1178

Essayez le code suivant. Il est réalisé en créant un subplot pour chaque indice niveau[0] dans votre cas année et en l'utilisant comme étiquette x. Et pour chaque subplot, nous traçons les données.

def plot_function(x, ax):
    ax = graph[x]
    ax.set_xlabel(x, weight='bold')
    return serotype_df.xs(x).plot(kind='bar', stacked='True', ax=ax, legend=False)

n_subplots = len(serotype_df.index.levels[0])
fig, axes = plt.subplots(nrows=1, ncols=n_subplots, sharey=True, figsize=(14, 8))  # largeur, hauteur

graph = dict(zip(serotype_df.index.levels[0], axes))
plots = list(map(lambda x: plot_function(x, graph[x]), graph))
ax.tick_params(axis='both', which='both', length=0)
fig.subplots_adjust(wspace=0)

plt.legend()
plt.show()

Si vous ne faites pas beaucoup de changements à chaque subplot, vous pouvez toujours faire ce qui suit :

plots = list(map(lambda x: serotype_df.xs(x).plot(kind='bar', stacked='True', ax=graph[x], legend=False).set_xlabel(x, weight='bold'), graph))

De cette façon, vous n'avez pas à créer ou à utiliser la fonction plot_function

enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X