2015-10-16 19 views
7

Quindi sto utilizzando seaborn per creare un kdeplot con sns.kdeplot(x, y, ax=plt.gca(), cmap="coolwarm").Come etichettare una trama di contorno Seaborn

Posso cambiare i livelli con il kwarg levels ma voglio anche poter etichettare i contorni. In matplotlib devi semplicemente fare plt.clabel(CS, CS.levels, inline=True) ma seaborn non restituisce la collezione di contorni CS.

Come faccio? O devo solo fare tutto da zero me stesso?

Modifica: C'è forse un modo per creare un wrapper che restituirà anche CS? Non riesco a vedere come se ...

+0

Sì, dovrete farlo da soli, anche se generalmente i valori di densità non sono particolarmente significativi o interessante. – mwaskom

+0

Stavo tentando di ottenere i livelli in modo da poter inserire una legenda. Ma dal momento che non sono particolarmente significativi, ho usato una funzione KDE personalizzata e ho invece tracciato i risultati (secondo il tuo consiglio). Grazie – Lucidnonsense

risposta

5

Sfortunatamente, Seaborn fa di tutto per mantenere il segreto del cliente da parte dell'utente. Oltre a tracciare un grafico dai dati, che in realtà non è troppo difficile, hai l'obolo di scimmiottare il seaborn _bivariate_kdeplot e lasciare che restituisca il countourset per un ulteriore utilizzo.

Questo potrebbe apparire come segue:

import matplotlib.pyplot as plt 
import numpy as np; np.random.seed(10) 
import seaborn as sns 
import seaborn.distributions as sd 
from seaborn.palettes import color_palette, blend_palette 
from six import string_types 


def _bivariate_kdeplot(x, y, filled, fill_lowest, 
         kernel, bw, gridsize, cut, clip, 
         axlabel, cbar, cbar_ax, cbar_kws, ax, **kwargs): 
    """Plot a joint KDE estimate as a bivariate contour plot.""" 
    # Determine the clipping 
    if clip is None: 
     clip = [(-np.inf, np.inf), (-np.inf, np.inf)] 
    elif np.ndim(clip) == 1: 
     clip = [clip, clip] 

    # Calculate the KDE 
    if sd._has_statsmodels: 
     xx, yy, z = sd._statsmodels_bivariate_kde(x, y, bw, gridsize, cut, clip) 
    else: 
     xx, yy, z = sd._scipy_bivariate_kde(x, y, bw, gridsize, cut, clip) 

    # Plot the contours 
    n_levels = kwargs.pop("n_levels", 10) 
    cmap = kwargs.get("cmap", "BuGn" if filled else "BuGn_d") 
    if isinstance(cmap, string_types): 
     if cmap.endswith("_d"): 
      pal = ["#333333"] 
      pal.extend(color_palette(cmap.replace("_d", "_r"), 2)) 
      cmap = blend_palette(pal, as_cmap=True) 
     else: 
      cmap = plt.cm.get_cmap(cmap) 

    kwargs["cmap"] = cmap 
    contour_func = ax.contourf if filled else ax.contour 
    cset = contour_func(xx, yy, z, n_levels, **kwargs) 
    if filled and not fill_lowest: 
     cset.collections[0].set_alpha(0) 
    kwargs["n_levels"] = n_levels 

    if cbar: 
     cbar_kws = {} if cbar_kws is None else cbar_kws 
     ax.figure.colorbar(cset, cbar_ax, ax, **cbar_kws) 

    # Label the axes 
    if hasattr(x, "name") and axlabel: 
     ax.set_xlabel(x.name) 
    if hasattr(y, "name") and axlabel: 
     ax.set_ylabel(y.name) 

    return ax, cset 

# monkey patching 
sd._bivariate_kdeplot = _bivariate_kdeplot 

# some data 
mean, cov = [0, 2], [(1, .5), (.5, 1)] 
x, y = np.random.multivariate_normal(mean, cov, size=50).T 

# plot 
fig, ax = plt.subplots() 
_, cs = sns.kdeplot(x, y, ax=ax, cmap="coolwarm") 
# label the contours 
plt.clabel(cs, cs.levels, inline=True) 
# add a colorbar 
fig.colorbar(cs) 

plt.show() 

enter image description here

+0

Proprio così! Questa patch consente anche di combinare la visualizzazione di riempimenti, linee ed etichette con lievi modifiche. Colorbar ha funzionato dopo l'aggiornamento di seaborn alla v0.8.1. – bejota

Problemi correlati