web-dev-qa-db-fra.com

Matplotlib - étiqueter chaque bac

J'utilise actuellement Matplotlib pour créer un histogramme:

enter image description here

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as pyplot
...
fig = pyplot.figure()
ax = fig.add_subplot(1,1,1,)
n, bins, patches = ax.hist(measurements, bins=50, range=(graph_minimum, graph_maximum), histtype='bar')

#ax.set_xticklabels([n], rotation='vertical')

for patch in patches:
    patch.set_facecolor('r')

pyplot.title('Spam and Ham')
pyplot.xlabel('Time (in seconds)')
pyplot.ylabel('Bits of Ham')
pyplot.savefig(output_filename)

J'aimerais rendre les étiquettes de l'axe X un peu plus significatives.

Tout d'abord, les graduations de l'axe des x semblent ici être limitées à cinq graduations. Peu importe ce que je fais, je n'arrive pas à changer cela - même si j'ajoute plus de xticklabels, il n'utilise que les cinq premiers. Je ne sais pas comment Matplotlib calcule cela, mais je suppose qu'il est calculé automatiquement à partir de la plage/des données?

Existe-t-il un moyen d'augmenter la résolution des étiquettes x-tick - même au point d'un pour chaque barre/bac?

(Idéalement, j'aimerais aussi que les secondes soient reformatées en micro-secondes/milli-secondes, mais c'est une question pour un autre jour).

Deuxièmement, je voudrais chaque barre individuelle étiquetée - avec le nombre réel dans ce bac, ainsi que le pourcentage du total de tous les bacs.

La sortie finale pourrait ressembler à ceci:

enter image description here

Est-ce que quelque chose comme ça est possible avec Matplotlib?

À la vôtre, Victor

63
victorhooi

Sûr! Pour régler les tiques, juste, eh bien ... Réglez les tiques (voir matplotlib.pyplot.xticks ou ax.set_xticks). (De plus, vous n'avez pas besoin de définir manuellement la couleur des correctifs. Vous pouvez simplement passer un argument de mot clé.)

Pour le reste, vous devrez faire des choses légèrement plus sophistiquées avec l'étiquetage, mais matplotlib le rend assez facile.

Par exemple:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import FormatStrFormatter

data = np.random.randn(82)
fig, ax = plt.subplots()
counts, bins, patches = ax.hist(data, facecolor='yellow', edgecolor='gray')

# Set the ticks to be at the edges of the bins.
ax.set_xticks(bins)
# Set the xaxis's tick labels to be formatted with 1 decimal place...
ax.xaxis.set_major_formatter(FormatStrFormatter('%0.1f'))

# Change the colors of bars at the edges...
twentyfifth, seventyfifth = np.percentile(data, [25, 75])
for patch, rightside, leftside in Zip(patches, bins[1:], bins[:-1]):
    if rightside < twentyfifth:
        patch.set_facecolor('green')
    Elif leftside > seventyfifth:
        patch.set_facecolor('red')

# Label the raw counts and the percentages below the x-axis...
bin_centers = 0.5 * np.diff(bins) + bins[:-1]
for count, x in Zip(counts, bin_centers):
    # Label the raw counts
    ax.annotate(str(count), xy=(x, 0), xycoords=('data', 'axes fraction'),
        xytext=(0, -18), textcoords='offset points', va='top', ha='center')

    # Label the percentages
    percent = '%0.0f%%' % (100 * float(count) / counts.sum())
    ax.annotate(percent, xy=(x, 0), xycoords=('data', 'axes fraction'),
        xytext=(0, -32), textcoords='offset points', va='top', ha='center')


# Give ourselves some more room at the bottom of the plot
plt.subplots_adjust(bottom=0.15)
plt.show()

enter image description here

104
Joe Kington

Pour ajouter des préfixes SI à vos étiquettes d'axe que vous souhaitez utiliser QuantiPhy . En fait, dans sa documentation, il a un exemple qui montre comment faire exactement cela: exemple MatPlotLib .

Je pense que vous ajouteriez quelque chose comme ça à votre code:

from matplotlib.ticker import FuncFormatter
from quantiphy import Quantity

time_fmtr = FuncFormatter(lambda v, p: Quantity(v, 's').render(prec=2))
ax.xaxis.set_major_formatter(time_fmtr)
0
August West