2015-08-28 13 views
7

Mam następujący kod:Jak dodać legendę na Seaborn facetgrid bar działki

import numpy as np 
import pandas as pd 
import matplotlib 
matplotlib.use('Agg') 
import matplotlib.pyplot as plt 
matplotlib.style.use('ggplot') 
import seaborn as sns 

sns.set(style="white") 

# Create a dataset with many short random walks 
rs = np.random.RandomState(4) 
pos = rs.randint(-1, 2, (10, 5)).cumsum(axis=1) 
pos -= pos[:, 0, np.newaxis] 
step = np.tile(range(5), 10) 
walk = np.repeat(range(10), 5) 
df = pd.DataFrame(np.c_[pos.flat, step, walk], 
        columns=["position", "step", "walk"]) 



# Initialize a grid of plots with an Axes for each walk 
grid = sns.FacetGrid(df, col="walk", hue="walk", col_wrap=5, size=5, 
     aspect=1) 


# Draw a bar plot to show the trajectory of each random walk 
grid.map(sns.barplot, "step", "position", palette="Set3").add_legend(); 

grid.savefig("/Users/mymacmini/Desktop/test_fig.png") 
#sns.plt.show() 

co czyni tę działki:

enter image description here

Jak widać mam legenda źle. Jak mogę to naprawić?

+0

Należy użyć 'factorplot', lub jeśli naprawdę chcesz używać' FacteGrid' bezpośrednio, trzeba przekazać zmienną hue' 'w' map'. – mwaskom

+0

@mwaskom Dziękuję bardzo. czy możesz podać przykład? Próbowałem tego, ale też się nie udało 'grid.map (sns.barplot," step "," position ", hue =" step ", palette =" Set3 "). Add_legend();' – neversaint

+0

To jest trzeci argument pozycyjny. Ale powinieneś naprawdę użyć 'factorplot' ... – mwaskom

Odpowiedz

10

Niektóre z elementów legendy dla każdego z podpól. Wygląda na to, że jeśli chcemy mieć legendę odpowiadającą paskom w każdym z wątków, musimy ręcznie je wykonać.

# Let's just make a 1-by-2 plot 
df = df.head(10) 

# Initialize a grid of plots with an Axes for each walk 
grid = sns.FacetGrid(df, col="walk", hue="walk", col_wrap=2, size=5, 
     aspect=1) 

# Draw a bar plot to show the trajectory of each random walk 
bp = grid.map(sns.barplot, "step", "position", palette="Set3") 

# The color cycles are going to all the same, doesn't matter which axes we use 
Ax = bp.axes[0] 

# Some how for a plot of 5 bars, there are 6 patches, what is the 6th one? 
Boxes = [item for item in Ax.get_children() 
     if isinstance(item, matplotlib.patches.Rectangle)][:-1] 

# There is no labels, need to define the labels 
legend_labels = ['a', 'b', 'c', 'd', 'e'] 

# Create the legend patches 
legend_patches = [matplotlib.patches.Patch(color=C, label=L) for 
        C, L in zip([item.get_facecolor() for item in Boxes], 
           legend_labels)] 

# Plot the legend 
plt.legend(handles=legend_patches) 

enter image description here

+0

Skąd pochodzą "a, b, c, d, e"? To nie odpowiada żadnemu elementowi w zestawie danych. – mwaskom

+3

Po prostu to wymyśliłem. Nie znajdował się on w fikcyjnym zbiorze danych (lub po prostu '[0, 1, 2, 3, 4]', wartości x). Zgaduję, że w prawdziwym zestawie danych OP może mieć znaczące etykiety związane z poszczególnymi klasami. –

+0

Myślę, że OP chce, aby etykiety legendy były unikalnymi wartościami w kolumnie "krok" danych –

Powiązane problemy