subplots examples example python numpy matplotlib scipy

python - examples - subplots



Matplotlib-Histograma escalonado con datos ya agrupados (4)

Estoy tratando de obtener un histograma con datos ya almacenados. He estado tratando de usar la bar() para esto, pero parece que no puedo entender cómo hacer que sea un histograma escalonado como este a partir de los ejemplos , en lugar de un histograma lleno.


De la fuente que acompaña en http://matplotlib.sourceforge.net/examples/pylab_examples/histogram_demo_extended.html

Aquí es cómo dibujaron esa gráfica:

[recorte]

y el bit que quieres parece ser

pylab.hist(x, bins=bins, histtype=''step'') ^ right here

Edición: si desea saber cómo funciona hist (), mire la fuente: está definida en matplotlib / axes.py a partir de la línea 7407.

Mirando la línea 7724,

x = np.zeros( 2*len(bins), np.float ) y = np.zeros( 2*len(bins), np.float )

para N barras, las bandejas son un numpy.ndarray de N + 1 valores, que son los bordes para cada barra. Combinan los valores de cada barra (esto es lo que hace fraxel con np.ravel a continuación) y desplazan los puntos de datos a la mitad de una barra izquierda para centrarlos

x[0::2], x[1::2] = bins, bins x -= 0.5*(bins[1]-bins[0])

establezca la altura de cada barra, hermanada pero desplazada en una (relativa a los valores de x) para producir el efecto de paso

# n is an array of arrays containing the number of items per bar patches = [] # from line 7676 for m, c in zip(n, color): y[1:-1:2], y[2::2] = m, m patches.append(self.fill(x, y, closed=False, edgecolor=c, fill=False))

y el bit self.fill es lo que realmente dibuja las líneas.


La solución más sencilla es convertir su conjunto de datos agrupado en un conjunto de datos ponderado no agrupado (con número de elementos == número de contenedores). El conjunto de datos no incorporados consistiría en valores de datos iguales a los centros del contenedor y ponderaciones iguales a los valores de cada contenedor. Por ejemplo, digamos que sus datos bineados son,

binedges = [0.0, 1.0, 2.0, 3.0] ybinned = [11., 22., 33.]

El conjunto de datos ponderado correspondiente sería,

y = [0.5, 1.5, 2.5] weights = [11., 22., 33.]

Tenga en cuenta que la opción de usar el centro del contenedor es arbitraria, puede usar cualquier punto dentro de un contenedor. Una vez que haya generado el conjunto de datos sin agrupar, puede usar el trazado normal del histograma de matplotlib (es decir, Axes.hist).

Una implementación de ejemplo en python sigue:

def plot_binned_data(axes, binedges, data, *args, **kwargs): #The dataset values are the bin centres x = (binedges[1:] + binedges[:-1]) / 2.0 #The weights are the y-values of the input binned data weights = data return axes.hist(x, bins=binedges, weights=weights, *args, **kwargs)

Ahora puede tener acceso completo a todas las opciones de trazado de Axes.Histogram, incluido histtype="step" para crear el histograma escalonado que deseaba.

Un ejemplo usando esta función sería,

import numpy import matplotlib.pyplot as plt #Create a dataset dataset = numpy.random.normal(size=100) #Bin the dataset binedges = numpy.linspace(-5.0, 5.0, num=10) y, binedges = numpy.histogram(dataset, binedges) #Plot the dataset fig = plt.figure() ax = fig.add_subplot(1, 1, 1) plot_binned_data(ax, binedges, y, histtype="step") plt.show()

¡Espero que ayude!


Por alguna razón, la última bandeja no se cierra correctamente cuando lo intento. No se ve en las respuestas anteriores si se muestra la última línea, así que decidí hacer mi propia función, que hace lo que quiero.

def make_bar_contour_plot(ax,x_input,y_input): x = list(np.ravel(zip(x_input[:-1],x_input[:-1]+1)))[1:] x += [x[-1]+20] + [300] y = list(np.ravel(zip(y_input,y_input))) +[0] ax.plot(x,y,ls=''steps'') return ax

Los 20 y 300 que se agregan son mi valor de binsize y final, respectivamente, y deben ajustarse si alguien quiere usar esto. x_input y y_input son los valores de np.histogram de np.histogram . Mi gráfico resultante (en azul el contorno, trazado con la función anterior. En rojo, el gráfico de barras de los mismos datos):


Puedes hacer trampa, compensando tus datos y usando la plot lugar:

from matplotlib import pyplot import numpy as np #sample data: x = np.arange(30) y = np.cumsum(np.arange(30)) #offset the x for horizontal, repeat the y for vertical: x = np.ravel(zip(x,x+1)) y = np.ravel(zip(y,y)) pyplot.plot(x,y) pyplot.savefig(''plt.png'')

la trama: