visualizacion una tiempo real hacer graficos graficas grafica error diagramas datos crear con como barras python numpy matplotlib stackedbarseries

una - python graficos 2d



Gráfico de barras apiladas matplotlib más eficientes: cómo calcular los valores mínimos (4)

Necesito ayuda para hacer un conjunto de gráficos de barras apiladas en python con matlibplot. Mi código básico está a continuación, pero mi problema es cómo generar el valor de abajo para cualquier elemento más allá del 2º de manera eficiente . Puedo obtener el gráfico de ejemplo para apilar correctamente (siempre a, b, c, d de abajo hacia arriba)

import numpy as np import matplotlib.pyplot as plt ind = np.arange(3) a = [3,6,9] b = [2,7,1] c = [0,3,1] d = [4,0,3] p1 = plt.bar(ind, a, 1, color=''#ff3333'') p2 = plt.bar(ind, b, 1, color=''#33ff33'', bottom=a) p3 = plt.bar(ind, c, 1, color=''#3333ff'', bottom=[a[j] +b[j] for j in range(len(a))]) p4 = plt.bar(ind, d, 1, color=''#33ffff'', bottom=[a[j] +b[j] +c[j] for j in range(len(a))]) plt.show()

Mi código final podría tener una gran cantidad de barras y la función de expansión constante bottom = [...] no puede ser la mejor solución. Sería genial si también pudieras explicar cómo necesito obtener el valor. ¿Hay una función numpy?

¡¡¡Muchas gracias!!! PD. He buscado una respuesta, pero no entendí qué podría encontrar.


La conversión de sus valores a matrices numpy hará su vida más fácil:

data = np.array([a, b, c, d]) bottom = np.cumsum(data, axis=0) colors = (''#ff3333'', ''#33ff33'', ''#3333ff'', ''#33ffff'') plt.bar(ind, data[0], color=colors[0]) for j in xrange(1, data.shape[0]): plt.bar(ind, data[1], color=colors[j], bottom=bottom[i-1])

Alternativamente, para deshacerse del desagradable caso particular de la primera barra:

data = np.array([a, b, c, d]) bottom = np.vstack((np.zeros((data.shape[1],), dtype=data.dtype), np.cumsum(data, axis=0)[:-1])) colors = (''#ff3333'', ''#33ff33'', ''#3333ff'', ''#33ffff'') for dat, col, bot in zip(data, colors, bottom): plt.bar(ind, dat, color=col, bottom=bot)


[sum(values) for values in zip(a, b, c)]

En Python 2 también puedes hacer

map(sum, zip(a, b, c))

pero Python 3 necesitaría

list(map(sum, zip(a, b, c)))

que es menos agradable

Podrías encapsular esto:

def sumzip(*items): return [sum(values) for values in zip(*items)]

y luego hacer

p1 = plt.bar(ind, a, 1, color=''#ff3333'') p2 = plt.bar(ind, b, 1, color=''#33ff33'', bottom=sumzip(a)) p3 = plt.bar(ind, c, 1, color=''#3333ff'', bottom=sumzip(a, b)) p4 = plt.bar(ind, d, 1, color=''#33ffff'', bottom=sumzip(a, b, c))

también.

Si a , b , c y d son matrices numpy, también puedes hacer sum([a, b, c]) :

a = np.array([3,6,9]) b = np.array([2,7,1]) c = np.array([0,3,1]) d = np.array([4,0,3]) p1 = plt.bar(ind, a, 1, color=''#ff3333'') p2 = plt.bar(ind, b, 1, color=''#33ff33'', bottom=sum([a])) p3 = plt.bar(ind, c, 1, color=''#3333ff'', bottom=sum([a, b])) p4 = plt.bar(ind, d, 1, color=''#33ffff'', bottom=sum([a, b, c]))


Recientemente me he enfrentado al mismo problema. Después, decidí envolverlo todo en una clase agradable. Para cualquier persona interesada, obtenga una implementación de una clase de gráfico de barras apiladas aquí:

https://github.com/minillinim/stackedBarGraph

Permite gráficos apilados a escala, así como establecer anchos de barra y establecer alturas (con internos escalados).

Dado un conjunto de datos como este:

d = np.array([[101.,0.,0.,0.,0.,0.,0.], [92.,3.,0.,4.,5.,6.,0.], [56.,7.,8.,9.,23.,4.,5.], [81.,2.,4.,5.,32.,33.,4.], [0.,45.,2.,3.,45.,67.,8.], [99.,5.,0.,0.,0.,43.,56.]]) d_heights = [1.,2.,3.,4.,5.,6.] d_widths = [.5,1.,3.,2.,1.,2.] d_labels = ["fred","julie","sam","peter","rob","baz"] d_colors = [''#2166ac'', ''#fee090'', ''#fdbb84'', ''#fc8d59'', ''#e34a33'', ''#b30000'', ''#777777'']

Puede hacer imágenes como esta:

GPLv3 con amor.


Lo solucioné así:

import numpy as np dates = # somehow get a list of dates labels = # a list of various labels colors = # somehow get a list of colors margin_bottom = np.zeros(dates) for index, label in enumerate(labels): values = # get your values for the label at index-th position from somewhere ax.bar( dates, values, align=''center'', label=label, color=colors[index], bottom=margin_bottom ) margin_bottom += values # here you simply add it to the previous margin # margin_bottom is a numpy array, adding a list will not change that

Es similar a algunas otras soluciones, pero no requiere que todos los márgenes se almacenen en todo momento. En su lugar, "construye" las pilas de abajo hacia arriba, agregando más y más margen con cada iteración.