Jak wykreślić różne słupki dla każdej wartości w kolumnie, gdzie każdy wykres odpowiada wartości w innej kolumnie?
Dec 04 2020
Mam tę ramkę danych, jak pokazano poniżej:
data = [['AK','Coal',24457],
['AK','Natural ',222867],
['AK','Other ',15],
['AK','Petro',83848],
['AL','Coal ',169877],
['AL','Natural ',10692],
['AL','Other ',2631],
['AL','Petro',235853]]
df = pd.DataFrame(data, columns = ['STATE','ENERGY','CONSUME'])
Próbuję narysować to na wykresie, który musi wyglądać jak ten obrazek:

Każdy słupek odpowiada wartości „CONSUME” dla odpowiedniej „ENERGII”. Jest to podobne do grupowania wartości w oparciu o „STAN” i kreślenia różnych słupków na podstawie „ENERGII”. Zasadniczo każdy „STAN” miałby 4 słupki wskazujące 4 różne wartości „ENERGII”. Próbowałem kilku rzeczy, ale nie działały tak, jak chciałem.
Odpowiedzi
Pygirl Dec 04 2020 at 15:30
Właśnie modyfikuję kod podany przez Scotta Bostona w jednej z jego odpowiedzi. Spójrz również na tę odpowiedź.
import pandas as pd
import matplotlib.pyplot as plt
from itertools import groupby
import numpy as np
%matplotlib inline
data = [['AK','Coal',24457],
['AK','Natural ',222867],
['AK','Other ',15],
['AK','Petro',83848],
['AL','Coal ',169877],
['AL','Natural ',10692],
['AL','Other ',2631],
['AL','Petro',235853]]
df = pd.DataFrame(data, columns = ['STATE','ENERGY','CONSUME'])
df = df.set_index(['STATE','ENERGY', 'STATE'])['CONSUME'].unstack()
def add_line(ax, xpos, ypos):
line = plt.Line2D([xpos, xpos], [ypos + .1, ypos],
transform=ax.transAxes, color='gray')
line.set_clip_on(False)
ax.add_line(line)
def label_len(my_index,level):
labels = my_index.get_level_values(level)
return [(k, sum(1 for i in g)) for k,g in groupby(labels)]
def label_group_bar_table(ax, df):
ypos = -.1
scale = 1./df.index.size
for level in range(df.index.nlevels)[::-1]:
pos = 0
for label, rpos in label_len(df.index,level):
lxpos = (pos + .5 * rpos)*scale
ax.text(lxpos, ypos, label, ha='center', transform=ax.transAxes)
add_line(ax, pos*scale, ypos)
pos += rpos
add_line(ax, pos*scale , ypos)
ypos -= .1
ax = df.plot(kind='bar')
#Below 2 lines remove default labels
ax.set_xticklabels('')
ax.set_xlabel('')
label_group_bar_table(ax, df)
