2015-07-08 3 views
2

У меня есть набор данных, которые я пытаюсь построить с помощью FacetGrid на морском побережье. Каждая точка данных имеет связанный с ней вес, и я хочу построить взвешенную гистограмму в каждой из фасет сетки.Как проехать грузы к морскому берегу FacetGrid

Например, скажем, у меня был следующий (в случайном порядке), созданный набор данных:

import seaborn as sns 
import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt 

d = pd.DataFrame(np.array([np.random.randint(0, 6, 5000), 
          np.random.normal(0, 1., 5000), 
          np.random.uniform(0, 1, 5000)]).T, 
       columns=('cat', 'val', 'weight')) 

Эти данные структурирована следующим образом:

cat  val weight 
0 0 -0.844542 0.668081 
1 0 -0.521177 0.521396 
2 1 -1.160358 0.788465 
3 0 -0.394765 0.115242 
4 5 0.735328 0.003495 

Обычно, если у меня не было весов, Я бы построил это так:

fg = sns.FacetGrid(d, col='cat', col_wrap=3) 
fg.map(plt.hist, 'val') 

Это делает сетку гистограмм, где каждая гистограмма показывает di stribution переменной val за одно значение категории cat.

Что я хотел бы сделать, это вес каждой гистограммы. Если бы я делал один гистограмму с Matplotlib, я хотел бы сделать это:

plt.hist(d.val, weights=d.weight) 

Я попытался пропусканием аргумента весов для FacetGrid.map, но возникает ошибку из-за способом Сиборна ломтиков данных внутри, чтобы сделать сетку:

fg.map(plt.hist, 'val', weights=d.weight) 

--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-33-1403d26cff86> in <module>() 
     9 
    10 fg = sns.FacetGrid(d, col='cat', col_wrap=3) 
---> 11 fg.map(plt.hist, 'val', weights=d.weight) 

/opt/conda/lib/python3.4/site-packages/seaborn/axisgrid.py in map(self, func, *args, **kwargs) 
    443 
    444    # Draw the plot 
--> 445    self._facet_plot(func, ax, plot_args, kwargs) 
    446 
    447   # Finalize the annotations and layout 

/opt/conda/lib/python3.4/site-packages/seaborn/axisgrid.py in _facet_plot(self, func, ax, plot_args, plot_kwargs) 
    527 
    528   # Draw the plot 
--> 529   func(*plot_args, **plot_kwargs) 
    530 
    531   # Sort out the supporting information 

/opt/conda/lib/python3.4/site-packages/matplotlib/pyplot.py in hist(x, bins, range, normed, weights, cumulative, bottom, histtype, align, orientation, rwidth, log, color, label, stacked, hold, **kwargs) 
    2894      histtype=histtype, align=align, orientation=orientation, 
    2895      rwidth=rwidth, log=log, color=color, label=label, 
-> 2896      stacked=stacked, **kwargs) 
    2897   draw_if_interactive() 
    2898  finally: 

/opt/conda/lib/python3.4/site-packages/matplotlib/axes/_axes.py in hist(self, x, bins, range, normed, weights, cumulative, bottom, histtype, align, orientation, rwidth, log, color, label, stacked, **kwargs) 
    5647     if len(w[i]) != len(x[i]): 
    5648      raise ValueError(
-> 5649       'weights should have the same shape as x') 
    5650   else: 
    5651    w = [None]*nx 

ValueError: weights should have the same shape as x 

Итак, есть ли способ сделать такой сюжет?

ответ

3

Вам нужно написать небольшую функцию обертки вокруг plt.hist, которая принимает вектор весов в качестве позиционного аргумента. Что-то вроде

def weighted_hist(x, weights, **kwargs): 
    plt.hist(x, weights=weights, **kwargs) 

g = sns.FacetGrid(df, ...) 
g.map(weighted_hist, "x_var", "weight_var") 
g.set_axis_labels("x_var", "count") 
Смежные вопросы