如何将权重传递给 Seaborn FacetGrid
How to pass weights to a Seaborn FacetGrid
我有一组数据,我正尝试在 seaborn 中使用 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')
这会生成一个直方图网格,其中每个直方图显示变量 val
对于类别 cat
.
的一个值的分布
我想做的是对每个直方图进行加权。如果我用 Matplotlib 制作一个直方图,我会这样做:
plt.hist(d.val, weights=d.weight)
我尝试将权重参数传递给 FacetGrid.map
,但由于 seaborn 在内部对数据进行切片以制作网格的方式而引发错误:
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
那么,有没有办法制作这样的情节?
您需要围绕 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")
我有一组数据,我正尝试在 seaborn 中使用 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')
这会生成一个直方图网格,其中每个直方图显示变量 val
对于类别 cat
.
我想做的是对每个直方图进行加权。如果我用 Matplotlib 制作一个直方图,我会这样做:
plt.hist(d.val, weights=d.weight)
我尝试将权重参数传递给 FacetGrid.map
,但由于 seaborn 在内部对数据进行切片以制作网格的方式而引发错误:
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
那么,有没有办法制作这样的情节?
您需要围绕 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")