web-dev-qa-db-fra.com

Python matplotlib barres multiples

Comment tracer plusieurs barres dans matplotlib, lorsque j’essaie d’appeler plusieurs fois la fonction de barre, elles se chevauchent et, comme le montre la figure ci-dessous, la valeur rouge la plus élevée ne peut être vue que .. .. Comment puis-je tracer plusieurs barres avec des dates x axes? 

Jusqu'ici, j'ai essayé ceci:

import matplotlib.pyplot as plt
  import datetime

    x = [datetime.datetime(2011, 1, 4, 0, 0),
         datetime.datetime(2011, 1, 5, 0, 0),
         datetime.datetime(2011, 1, 6, 0, 0)]
    y = [4, 9, 2]
    z=[1,2,3]
    k=[11,12,13]

    ax = plt.subplot(111)
    ax.bar(x, y,width=0.5,color='b',align='center')
    ax.bar(x, z,width=0.5,color='g',align='center')
    ax.bar(x, k,width=0.5,color='r',align='center')
    ax.xaxis_date()

    plt.show()

J'ai eu ceci: 

enter image description here

Les résultats devraient ressembler à quelque chose, mais avec les dates sur les axes x et les barres les unes à côté des autres: 

enter image description here

41
John Smith
import matplotlib.pyplot as plt
from matplotlib.dates import date2num
import datetime

x = [datetime.datetime(2011, 1, 4, 0, 0),
     datetime.datetime(2011, 1, 5, 0, 0),
     datetime.datetime(2011, 1, 6, 0, 0)]
x = date2num(x)

y = [4, 9, 2]
z=[1,2,3]
k=[11,12,13]

ax = plt.subplot(111)
ax.bar(x-0.2, y,width=0.2,color='b',align='center')
ax.bar(x, z,width=0.2,color='g',align='center')
ax.bar(x+0.2, k,width=0.2,color='r',align='center')
ax.xaxis_date()

plt.show()

enter image description here

Je ne sais pas ce que signifie "les valeurs y se chevauchent également", le code suivant résout-il votre problème?

ax = plt.subplot(111)
w = 0.3
ax.bar(x-w, y,width=w,color='b',align='center')
ax.bar(x, z,width=w,color='g',align='center')
ax.bar(x+w, k,width=w,color='r',align='center')
ax.xaxis_date()
ax.autoscale(tight=True)

plt.show()

enter image description here

66
HYRY

Le problème avec l'utilisation de dates en tant que valeurs x, est que si vous voulez un graphique à barres comme dans votre deuxième image, elles se tromperont. Vous devez soit utiliser un graphique à barres empilées (couleurs superposées), soit regrouper par date (une "fausse" date sur l'axe des x, regroupant simplement les points de données).

import numpy as np
import matplotlib.pyplot as plt

N = 3
ind = np.arange(N)  # the x locations for the groups
width = 0.27       # the width of the bars

fig = plt.figure()
ax = fig.add_subplot(111)

yvals = [4, 9, 2]
rects1 = ax.bar(ind, yvals, width, color='r')
zvals = [1,2,3]
rects2 = ax.bar(ind+width, zvals, width, color='g')
kvals = [11,12,13]
rects3 = ax.bar(ind+width*2, kvals, width, color='b')

ax.set_ylabel('Scores')
ax.set_xticks(ind+width)
ax.set_xticklabels( ('2011-Jan-4', '2011-Jan-5', '2011-Jan-6') )
ax.legend( (rects1[0], rects2[0], rects3[0]), ('y', 'z', 'k') )

def autolabel(rects):
    for rect in rects:
        h = rect.get_height()
        ax.text(rect.get_x()+rect.get_width()/2., 1.05*h, '%d'%int(h),
                ha='center', va='bottom')

autolabel(rects1)
autolabel(rects2)
autolabel(rects3)

plt.show()

enter image description here

28
jozzas

Je sais qu'il s'agit d'environ matplotlib, mais utiliser pandas et seaborn peut vous faire gagner beaucoup de temps:

df = pd.DataFrame(Zip(x*3, ["y"]*3+["z"]*3+["k"]*3, y+z+k), columns=["time", "kind", "data"])
plt.figure(figsize=(10, 6))
sns.barplot(x="time", hue="kind", y="data", data=df)
plt.show()

 enter image description here 

3
liwt31

J'ai fait cette solution: si vous voulez tracer plus d'un tracé dans une figure, assurez-vous qu'avant de tracer les tracés suivants, vous avez défini la fonction correcte matplotlib.pyplot.hold(True)pour l'ajout d'un autre tracé.

À propos des valeurs datetime sur X ax, la solution utilisant l’alignement des barres me convient. Lorsque vous créez un autre graphique à barres avec matplotlib.pyplot.bar(), utilisez simplement align='Edge|center' et définissez width='+|-distance'.

Lorsque vous réglez toutes les barres (tracés) à droite, vous verrez les barres bien.

0
Dave