【问题标题】:Python: weighted violinplotsPython:加权小提琴图
【发布时间】:2016-08-20 17:34:09
【问题描述】:

我必须大量使用加权概率分布,并且想使用小提琴图进行一些可视化。但是,我找不到在任何常见的嫌疑人(matplotlib、seaborn、bokeh 等)中使用加权数据创建这些的方法。

是否有人知道允许使用加权数据的实现或可能的解决方法?由于我的数据集很大,从加权数据重新创建人工未加权分布是不可行的。 R 有一个 wvioplot 包,但我真的很想坚持使用 Python。

【问题讨论】:

  • 您使用什么方法来加权数据?你是说你找不到为你实现这个方法的包?
  • 谢谢@AniMenon,效果很好!
  • @sllrp 很高兴知道,我在下面添加了答案以供参考。

标签: python matplotlib plot seaborn violin-plot


【解决方案1】:

答案发布以供参考:

import weighted
from matplotlib.cbook import violin_stats
from scipy import stats
import statsmodels.api as sm

def vdensity_with_weights(weights):
    ''' Outer function allows innder function access to weights. Matplotlib
    needs function to take in data and coords, so this seems like only way
    to 'pass' custom density function a set of weights '''

    def vdensity(data, coords):
        ''' Custom matplotlib weighted violin stats function '''
        # Using weights from closure, get KDE fomr statsmodels
        weighted_cost = sm.nonparametric.KDEUnivariate(data)
        weighted_cost.fit(fft=False, weights=weights)

        # Return y-values for graph of KDE by evaluating on coords
        return weighted_cost.evaluate(coords)
    return vdensity

def custom_violin_stats(data, weights):
    # Get weighted median and mean (using weighted module for median)
    median = weighted.quantile_1D(data, weights, 0.5)
    mean, sumw = np.ma.average(data, weights=list(weights), returned=True)

    # Use matplotlib violin_stats, which expects a function that takes in data and coords
    # which we get from closure above
    results = violin_stats(data, vdensity_with_weights(weights))

    # Update result dictionary with our updated info
    results[0][u"mean"] = mean
    results[0][u"median"] = median

    # No need to do this, since it should be populated from violin_stats
    # results[0][u"min"] =  np.min(data)
    # results[0][u"max"] =  np.max(data)

    return results

### Example
#vpstats1 = custom_violin_stats(np.asarray(df_column_data), np.asarray(df_column_weights))
#vplot = ax.violin(vpstats1, [pos_idx], vert=False, showmeans=True, showextrema=True, showmedians=True)
#current_color_palette = ...
#for pc in vplot['bodies']:
#    pc.set_facecolor(current_color_palette[pos_idx])
#    pc.set_edgecolor('black')

这个答案来自:here

【讨论】:

  • 此代码不运行。 weighted 不是标准发行版中的模块。 numpy 好像用过但没有导入。
  • 加权包实际上是 wquantiles 包,令人困惑。由于未知原因,它是使用 import weighted 导入的。
猜你喜欢
  • 2017-09-03
  • 1970-01-01
  • 2017-08-30
  • 2021-03-07
  • 1970-01-01
  • 2022-07-14
  • 2021-10-23
  • 2020-12-19
  • 2021-08-27
相关资源
最近更新 更多