2015-10-16 35 views
7

Używam seaborn do stworzenia kdeplot z sns.kdeplot(x, y, ax=plt.gca(), cmap="coolwarm").Jak oznaczyć etykieta konturowa seaborn

Mogę zmieniać poziomy za pomocą levels kwarg, ale chcę również móc opisywać kontury. W matplotlib po prostu zrobiłbyś plt.clabel(CS, CS.levels, inline=True), ale seaborn nie zwraca kolekcji konturów CS.

Jak to zrobić? Czy muszę po prostu zrobić to wszystko od podstaw?

Edycja: Czy istnieje sposób na utworzenie opakowania, które również zwróci CS? Nie widzę, jak ...

+0

Tak, będziesz musiał zrobić to sam, chociaż na ogół wartości gęstości nie są szczególnie istotne lub ciekawe. – mwaskom

+0

Próbowałem uzyskać poziomy, więc mogłem wstawić legendę. Ale ponieważ nie mają one szczególnego znaczenia, użyłem niestandardowej funkcji KDE i wydrukowałem wyniki (na twoją radę). Dzięki – Lucidnonsense

Odpowiedz

5

Niestety, seaborn robi wszystko, aby zachować tajemnicę od użytkownika. Oprócz rysowania wykresu plt.contour z danych, które w rzeczywistości nie jest zbyt trudne, masz dostęp do małpiej łatki seaborn _bivariate_kdeplot i pozwól mu zwrócić zestaw do dalszego wykorzystania.

To może wyglądać następująco:

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

Już wkrótce! Łata ta umożliwia również łączenie wyświetlania konturów, linii i etykiet z niewielkimi zmianami. Colorbar pracował po aktualizacji seaborn do wersji 0.8.1. – bejota