2
votes

Comment combiner 2 histogrammes de dataframe en 1 tracé?

Je voudrais utiliser un code qui montre tous les histogrammes dans un dataframe. Ce sera df.hist (bins = 10) . Cependant, je voudrais ajouter un autre histogramme qui montre CDF df_hist=df.hist(cumulative=True,bins=100,density=1,histtype="step")

J'ai essayé de séparer leurs axes matplotlib en utilisant fig = plt.figure () et plt.subplot (211) . Mais ce df.hist fait en fait partie de la fonction pandas, pas de la fonction matplotlib. J'ai également essayé de définir des axes et d'ajouter des options ax = ax1 et ax2 à chaque histogramme, mais cela n'a pas fonctionné.

Comment puis-je combiner ces histogrammes ensemble? Avez-vous de l'aide?

Les histogrammes que je souhaite combiner sont comme ceux-ci. Je veux les montrer côte à côte ou mettre le second sur la pointe du premier. Désolé de ne pas me soucier de leur donner une belle apparence. histogramme1 histogram2


1 commentaires

3 Réponses :


0
votes

Vous pouvez trouver plus d'informations ici: Histogrammes multiples dans Pandas (duplication possible btw) mais apparemment, les pandas ne peuvent pas gérer plusieurs histogrammes sur les mêmes graphiques.

C'est correct car np.histogram et matplotlib.pyplot peuvent , consultez le lien ci-dessus pour une réponse plus complète.


0 commentaires

3
votes

Il est possible de les rassembler:

fig, axes = plt.subplots(10,4, figsize=(16,10))
hist_axes = axes.flatten()[:20]
df.plot(kind='hist', subplots=True, ax=hist_axes, alpha=0.5)

kde_axes = axes.flatten()[20:]
df.plot(kind='kde', subplots=True, ax=kde_axes, alpha=0.5)

Sortie:

 entrez la description de l'image ici

Il est également possible de les dessiner côte à côte. Par exemple,

# toy data frame
df = pd.DataFrame(np.random.normal(0,1,(100,20)))

# draw hist
fig, axes = plt.subplots(5,4, figsize=(16,10))
df.plot(kind='hist', subplots=True, ax=axes, alpha=0.5)

# clone axes so they have different scales
ax_new = [ax.twinx() for ax in axes.flatten()]
df.plot(kind='kde', ax=ax_new, subplots=True)
plt.show()

tracera l'hist au-dessus de kde.


5 commentaires

Merci pour les complots. Cependant, puis-je l'utiliser lorsque le nombre de parcelles n'est pas égal? Comme vous le voyez, mon dataframe a 53 axes et ne me laisse pas faire de tracés avec plt.sublots () . Le message d'erreur est Le nombre d'axes passés doit être 53, le même que le tracé de sortie . Y-a-t-il un moyen d'éviter ça?


S'agit-il d'un matplotlib.style disponible que vous utilisez pour ces tracés? J'aime beaucoup la palette de couleurs (à part le noir de la deuxième rangée)!


Oui, j'aime aussi ce style. J'aimerais savoir quel style vous utilisez. Cependant, je pourrais réussir à éviter l'erreur en réaffectant les axes de cette manière. axes = df.plot (kind = 'hist', subplots = True, ax = axes, layout = (8,7), alpha = 0.5, legend = False) et df.plot (kind = 'kde', ax = axes.flatten () [: 53], layout = (8,7), subplots = True, legend = False) Mais cela n'a pas l'air bien. Tous les axes x sont fixes. Il semble que j'ai besoin de les trier un par un.


@Tim Je ne sais pas de quel style il s'agissait, fourni avec jupyterthemes .


J'ai peu de choses à modifier, mais il semble que ce soit la solution à ce que j'essaie de faire. Merci beaucoup pour la réponse.



0
votes

Il est possible de combiner deux figures d'histogramme de dataframe en utilisant les pandas df.hist . Il est également possible de le faire fonctionner pour un nombre impair de parcelles. Voici un exemple d'histogrammes combinés avec des histogrammes à pas cumulatifs où la disposition et la taille de la grille des tracés sont automatiquement prises en charge:

# Create lists of axes for each type of plot
axs_hist = axs.flatten()[:plot_types*nvar:plot_types]
axs_cumh = axs.flatten()[1:plot_types*nvar:plot_types]

# Create plots by looping through lists of axes and create a list of 
# all y-axis limits
axs_hist_ylims = []
for i, var_name, axh, axc in zip(range(nvar), df.columns, axs_hist, axs_cumh):
    axh.hist(df.iloc[:, i:i+1], bins=bins, edgecolor='white', linewidth=0.5)
    axh.set_title(f'{var_name} - Histogram')
    axs_hist_ylims.append(axh.get_ylim())
    axc.hist(df.iloc[:, i:i+1], bins=bins, density=True, cumulative=True,
             histtype='step', color='tab:orange', linewidth=2)
    axc.set_title(f'{var_name} - Cumulative step hist.')

# Set shared y-axis for histograms
for ax in axs_hist:
    ax.set_ylim(max(axs_hist_ylims))

plt.show()
# Set parameters for formatting grid layout and figure size
nvar = df.columns.size
plot_types = 2 # normal histogram and cumulative step histogram
var_cols = 2
rows = int(np.ceil(nvar/var_cols))
width = 10/(plot_types*var_cols)
height = 0.75*width
bins = 10

# Create figure with appropriate format and number of axes
fig, axs = plt.subplots(nrows=rows, ncols=plot_types*var_cols,
                        figsize=(plot_types*var_cols*width, rows*height))
fig.subplots_adjust(wspace=0.4, hspace=0.6)

# Remove unnecessary axes otherwise their frames will be shown empty
for ax in axs.flatten()[plot_types*nvar:]:
    ax.remove()

grid_hist_overlaid

À ma connaissance, il n'est pas possible d'afficher les différents types de tracés côte à côte avec df.hist . Vous devez créer la figure à partir de zéro, comme dans cet exemple qui utilise le même jeu de données qu'auparavant:

# Plot grid of histograms with pandas function (with a shared y-axis)
grid = df.hist(grid=False, sharey=True, figsize=(cols*width, rows*height),
               layout=(rows, cols), bins=bins, edgecolor='white', linewidth=0.5)

# Create list of twin axes containing second y-axis: note that due to the
# layout, the grid object may contain extra unused axes that are not shown
# (here in the H and I positions). The ax parameter of df.hist only accepts
# a number of axes that corresponds to the number of numerical variables
# in df, which is why the flattened array of grid axes is sliced here.
grid_twinx = [ax.twinx() for ax in grid.flatten()[:df.columns.size]]

# Plot cumulative step histograms over normal histograms: note that the
# layout of the grid is preserved in grid_twinx so no need to set the
# layout parameter a second time here.
df.hist(ax=grid_twinx, histtype='step', bins=bins, cumulative=True, density=True, 
        color='tab:orange', linewidth=2, grid=False)

# Adjust space between plots
plt.gcf().subplots_adjust(wspace=0.4, hspace=0.4)

plt.show()
import numpy as np                 # v 1.19.2
import pandas as pd                # v 1.1.3
import matplotlib.pyplot as plt    # v 3.3.2

# Create random data stored in a pandas dataframe
rng = np.random.default_rng(seed=1)
letters = [chr(i) for i in range(ord('A'), ord('G')+1)]
df = pd.DataFrame(data=rng.exponential(scale=1.0, size=(100, len(letters))),
                  columns=letters)

# Set parameters for formatting grid layout and figure size
plots = df.columns.size
cols = 3
rows = int(np.ceil(plots/cols))
width = 10/cols
height = 0.75*width
bins = 10

 grid_hist_cumh

Notez que la largeur des chiffres est définie plutôt basse pour produire l'image nette montrée ici (en raison des limitations de taille d'image). Un écran d'ordinateur moyen devrait facilement accueillir un paramètre de width = 15 / cols ou plus pour obtenir des tracés plus grands.


0 commentaires