2017-06-02 43 views
8

Chciałbym utworzyć wykres rozproszenia pand z DataFrame z kategorycznymi etykietami wierszy i kolumn przy użyciu matplotlib. Przykładowa DataFrame wygląda następująco:Parsowanie wykresów DataFrame z kategorycznie oznaczonymi wierszami/kolumnami

Rozmiar znacznika jest funkcją odpowiednich wartości DataFrame. Do tej pory, ja przyszedłem z niezręcznej rozwiązanie, które zasadniczo wylicza wierszy i kolumn, działki dane, a następnie rekonstruuje etykiety:

flat = df.reset_index(drop=True).T.reset_index(drop=True).T.stack().reset_index() 
# level_0 level_1 0 
#0  0  0 1 
#1  0  1 2 
#2  1  0 3 
#3  1  1 4 

flat.plot(kind='scatter', x='level_0', y='level_1', s=100*flat[0]) 
plt.xticks(range(df.shape[1]), df.columns) 
plt.yticks(range(df.shape[0]), df.index) 
plt.show() 

Jaki rodzaj prac. Which kind of works

Teraz pytanie: czy istnieje bardziej intuicyjny, bardziej zintegrowany sposób tworzenia tego wykresu rozproszonego, najlepiej bez podziału danych i metadanych?

+0

Nie sądzę, możemy korzystać z danych liczbowych dla non-kreślenia. AFAIK i tak będziesz musiał ustawić takty oddzielnie ... – MaxU

+1

Domyślam się, że pytanie tłumaczy się w * "Dlaczego żadna biblioteka nie zaimplementowała mojej niestandardowej funkcji życzeń?" *. – ImportanceOfBeingErnest

Odpowiedz

7

Może nie cała odpowiedź jesteś szukasz, ale pomysł, aby pomóc zaoszczędzić czas i czytelność linii flat=.

Pandy unstack Metoda spowoduje wyprodukowanie Serii z MultiIndex.

dfu = df.unstack() 

print(dfu.index) 
MultiIndex(levels=[[u'a', u'b'], [u'c', u'd']], 
      labels=[[0, 0, 1, 1], [0, 1, 0, 1]]) 

MultiIndex zawiera zawiera niezbędne x i punkty y do budowy powierzchni (w labels). Tutaj przypisuję levels i labels do bardziej szczegółowych nazw zmiennych, które lepiej nadają się do kreślenia.

xlabels, ylabels = dfu.index.levels 
xs, ys = dfu.index.labels 

Wykreślanie jest tutaj całkiem proste.

plt.scatter(xs, ys, s=dfu*100) 
plt.xticks(range(len(xlabels)), xlabels) 
plt.yticks(range(len(ylabels)), ylabels) 
plt.show() 

enter image description here

Próbowałem to na kilku różnych kształtach i DataFrame wydawało się pomieścić.

4

To nie jest dokładnie to, co zostało z prośbą o, ale to pomaga wizualizować wartości w podobny sposób:

import seaborn as sns 

sns.heatmap(df[::-1], annot=True) 

Wynik:

enter image description here

+0

Cóż ... To jest seaborn, nie matplotlib. Ale dzięki! – DyZ

3

Może można użyć tablicy numpy i pd.melt stworzyć wykres punktowy, jak pokazano poniżej:

arr = np.array([[i,j] for i in range(df.shape[1]) for j in range(df.shape[0])]) 
plt.scatter(arr[:,0],arr[:,1],s=100*pd.melt(df)['value'],marker='o') 
plt.xlabel('level_0') 
plt.ylabel('level_1') 
plt.xticks(range(df.shape[1]), df.columns) 
plt.yticks(range(df.shape[0]), df.index) 
plt.show() 

enter image description here