2

1 ~ 5 の数字をそれぞれ約 100 万回含むリストの箱ひげ図を作成したいとします。

このようなリストのサイズは約 5 000 000 になりますが、dict として表されると、スペースはまったく必要ありません。

s = {1: 1000000, 2: 1000000, 3: 1000000, 4: 1000000, 5:1000000}

問題は、その辞書の箱ひげ図を作成しようとすると、エラーが発生することです

Traceback (most recent call last):
  File "<pyshell#17>", line 1, in <module>
    ax.boxplot(s)
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/axes.py", line 5462, in boxplot
    if not hasattr(x[0], '__len__'):
KeyError: 0

sすべての要素をリストに入れることなく、辞書をボックスプロットする賢い方法はありますか?


コメントは私が試してみることを提案しました

boxplot(n for n, count in s.iteritems() for _ in xrange(count))

しかし、これは

Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    boxplot(n for n, count in s.iteritems() for _ in xrange(count))
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/pyplot.py", line 2134, in boxplot
    ret = ax.boxplot(x, notch, sym, vert, whis, positions, widths, patch_artist, bootstrap)
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/matplotlib/axes.py", line 5462, in boxplot
    if not hasattr(x[0], '__len__'):
TypeError: 'generator' object has no attribute '__getitem__'
4

2 に答える 2

4

データを説明するために画像を使用することの要点は、データを全体として把握することであり、ひどく正確である必要はありません。したがって、1000 個の実際のデータ ポイントごとに 1 つの代表的なデータ ポイントを生成することによって、データを圧縮しても大きな害はありません。

x = [val for val, num in s.items() for i in range(num//1000)]

肉眼ではこれで十分です。

import matplotlib.pyplot as plt
import numpy as np
s = {1: 1000000, 2: 1000000, 3: 1000000, 4: 1000000, 5:1000000}
x = [val for val, num in s.items() for i in range(num//1000)]
dct = plt.boxplot(x)
plt.show()
于 2012-11-12T17:48:56.453 に答える
2

私の知る限り、matplotlib にはそのようなデータ用のメソッドがありません。基本的に、関連する統計を計算し、箱ひげ図をプロットするための独自の方法を実装する必要があります。これはあなたを始めるかもしれません:

import matplotlib.pyplot as plt
import numpy as np


s = [{1: 1000000, 2: 1000000, 3: 1000000, 4: 1000000, 5:1000000},
     {1: 1000000, 0: 1000000, 8: 1000000, 3: 1000000, 7:1000000}]

def boxplot(data, x=0):

    sorted_data = np.array(data.items())
    sorted_data = np.sort(sorted_data, 0)
    values = sorted_data[:,0]
    freqs = sorted_data[:,1]
    freqs = np.cumsum(freqs)
    freqs = freqs*1./np.max(freqs)

    #get 25%, 50%, 75% percentiles
    idx = np.searchsorted(freqs, [0.25, 0.5, 0.75])
    p25, p50, p75 = values[idx]
    vmin, vmax = values.min(), values.max()

    ax = plt.gca()
    l,r = -0.2+x, 0.2+x
    #plot boxes
    plt.plot([l,r], [p50, p50], 'k')
    plt.plot([l, r, r, l, l], [p25, p25, p75, p75, p25], 'k')
    plt.plot([x,x], [p75, vmax], 'k')
    plt.plot([x,x], [p25, vmin], 'k')

for i in range(len(s)):
    boxplot(s[i],i)
plt.xlim(-0.5,1.5)
plt.show()
于 2012-11-12T17:30:06.580 に答える