2

Python の通常の matplotlib boxplot コマンドは、ボックス、中央値、ウィスカー、フライヤー、およびキャップのキーを含む辞書を返します。これにより、スタイリングが非常に簡単になります。

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

# Create a dataframe and subset it for a boxplot
df1 = pd.DataFrame(rand(10), columns=['Col1'] )
df1['X'] = pd.Series(['A','B','A','B','A','B','A','B','A','B'])
boxes= [df1[df1['X'] == 'A'].Col1, df1[df1['X'] == 'B'].Col1]

# Call the standard matplotlib boxplot function,
# which returns a dictionary including the parts of the graph
mbp = plt.boxplot(boxes)
print(type(mbp))

# This dictionary output makes styling the boxplot easy
plt.setp(mbp['boxes'], color='blue')
plt.setp(mbp['medians'], color='red')
plt.setp(mbp['whiskers'], color='blue')
plt.setp(mbp['fliers'], color='blue')

Pandas ライブラリには、グループ化された (階層的にインデックス化された) データフレーム用の「最適化された」boxplot 関数があります。ただし、グループごとに複数の辞書を返す代わりに、matplotlib.axes.AxesSubplot オブジェクトを返します。これはスタイリングを非常に困難にします。

# Pandas has a built-in boxplot function that returns
# a matplotlib.axes.AxesSubplot object
pbp = df1.boxplot(by='X')
print(type(pbp))

# Similar attempts at styling obviously return TypeErrors
plt.setp(pbp['boxes'], color='blue')
plt.setp(pbp['medians'], color='red')
plt.setp(pbp['whiskers'], color='blue')
plt.setp(pbp['fliers'], color='blue')

pandas df.boxplot(by='X') 関数によって生成されたこの AxisSubplot オブジェクトはアクセス可能ですか?

4

2 に答える 2

8

return_typeas を指定することもできますdict。これにより、箱ひげ図にプロットされた各列によってインデックス付けされた辞書に、箱ひげ図のプロパティが直接返されます。

上記の例を (IPython で) 使用するには:

from pandas import *
import matplotlib
from numpy.random import rand
import matplotlib.pyplot as plt
df = DataFrame(rand(10,2), columns=['Col1', 'Col2'] )
df['X'] = Series(['A','A','A','A','A','B','B','B','B','B'])
bp = df.boxplot( by='X', return_type='dict' )

>>> bp.keys()
['Col1', 'Col2']

>>> bp['Col1'].keys()
['boxes', 'fliers', 'medians', 'means', 'whiskers', 'caps']

さて、線幅の変更はリスト内包の問題です:

>>> [ [item.set_linewidth( 2 ) for item in bp[key]['medians']] for key in bp.keys() ]
[[None, None], [None, None]]
于 2015-01-23T05:07:42.163 に答える
2

ハードコーディングする必要があるのではないかと心配しています。例を見てみましょうpandas: http://pandas.pydata.org/pandas-docs/stable/visualization.html#box-plotting

from pandas import *
import matplotlib
from numpy.random import rand
import matplotlib.pyplot as plt
df = DataFrame(rand(10,2), columns=['Col1', 'Col2'] )
df['X'] = Series(['A','A','A','A','A','B','B','B','B','B'])
bp = df.boxplot(by='X')
cl=bp[0].get_children()
cl=[item for item in cl if isinstance(item, matplotlib.lines.Line2D)]

次に、どれがボックス、メジアンなどであるかを識別しましょう。

for i, item in enumerate(cl):
    if item.get_xdata().mean()>0:
        bp[0].text(item.get_xdata().mean(), item.get_ydata().mean(), str(i), va='center', ha='center')

プロットは次のようになります。

ここに画像の説明を入力

各バーは 8 つの項目で構成されます。例: 5 番目の項目は中央値です。7 番目と 8 番目のアイテムはおそらくフライヤーですが、ここにはありません。

これらを知っていれば、バーの一部を変更するのは簡単です。中央値をlinewidth2 に設定したい場合:

for i in range(_your_number_of_classes_2_in_this_case):
    cl[5+i*8].set_linewidth(2.)
于 2013-10-18T17:30:38.173 に答える