はじめに
この実験では、Matplotlib の円グラフでフィルタリング効果をどのように使用するかを示します。円グラフの描画コードは pie_demo.py から借用し、グラフにフィルタリング効果を追加します。フィルタリング効果は、SVG レンダラがサポートしている場合にのみ有効です。
VM のヒント
VM の起動が完了したら、左上隅をクリックしてノートブックタブに切り替え、Jupyter Notebook を使って練習しましょう。
Jupyter Notebook の読み込みには数秒かかる場合があります。Jupyter Notebook の制限により、操作の検証は自動化できません。
学習中に問題がある場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。
円グラフを作成する
円グラフ用の正方形の図と軸を作成します。円グラフのラベルと割合を定義します。また、円グラフのサイスに対する爆発値も設定します。最後に、定義されたパラメータで円グラフを描画します。
import matplotlib.pyplot as plt
from matplotlib.patches import Shadow
fig = plt.figure(figsize=(6, 6))
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
fracs = [15, 30, 45, 10]
explode = (0, 0.05, 0, 0)
pies = ax.pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%')
for w in pies[0]:
w.set_gid(w.get_label())
w.set_edgecolor("none")
for w in pies[0]:
s = Shadow(w, -0.01, -0.01)
s.set_gid(w.get_gid() + "_shadow")
s.set_zorder(w.get_zorder() - 0.1)
ax.add_patch(s)
plt.show()
グラフを SVG として保存する
io と xml.etree.ElementTree モジュールを使って、円グラフを SVG ファイルとして保存します。ガウシアンブラーと照明効果を使って、シャドウ用のフィルタ定義を定義します。照明フィルタは http://www.w3.org/TR/SVG/filters.html からコピーしました。Inkscape と Firefox3 を使ってフィルタをテストしますが、Inkscape のエクスポートはサポートしていない場合があります。
import io
import xml.etree.ElementTree as ET
f = io.BytesIO()
plt.savefig(f, format="svg")
filter_def = """
<defs xmlns='http://www.w3.org/2000/svg'
xmlns:xlink='http://www.w3.org/1999/xlink'>
<filter id='dropshadow' height='1.2' width='1.2'>
<feGaussianBlur result='blur' stdDeviation='2'/>
</filter>
<filter id='MyFilter' filterUnits='objectBoundingBox'
x='0' y='0' width='1' height='1'>
<feGaussianBlur in='SourceAlpha' stdDeviation='4%' result='blur'/>
<feOffset in='blur' dx='4%' dy='4%' result='offsetBlur'/>
<feSpecularLighting in='blur' surfaceScale='5' specularConstant='.75'
specularExponent='20' lighting-color='#bbbbbb' result='specOut'>
<fePointLight x='-5000%' y='-10000%' z='20000%'/>
</feSpecularLighting>
<feComposite in='specOut' in2='SourceAlpha'
operator='in' result='specOut'/>
<feComposite in='SourceGraphic' in2='specOut' operator='arithmetic'
k1='0' k2='1' k3='1' k4='0'/>
</filter>
</defs>
"""
tree, xmlid = ET.XMLID(f.getvalue())
tree.insert(0, ET.XML(filter_def))
for i, pie_name in enumerate(labels):
pie = xmlid[pie_name]
pie.set("filter", 'url(#MyFilter)')
shadow = xmlid[pie_name + "_shadow"]
shadow.set("filter", 'url(#dropshadow)')
fn = "svg_filter_pie.svg"
print(f"Saving '{fn}'")
ET.ElementTree(tree).write(fn)
フィルタリング効果付きの円グラフを表示する
適用されたフィルタリング効果付きの円グラフを表示します。Inkscape を使って SVG ファイルを開き、フィルタリング効果付きの円グラフを表示します。
異なるフィルタを使って円グラフを変更する
フィルタ定義を変更することで、異なるフィルタを使って円グラフを変更できます。異なる視覚的な効果を得るために、さまざまなフィルタを試してみることができます。
filter_def = """
<defs xmlns='http://www.w3.org/2000/svg'
xmlns:xlink='http://www.w3.org/1999/xlink'>
<filter id='dropshadow' height='1.2' width='1.2'>
<feGaussianBlur result='blur' stdDeviation='2'/>
</filter>
<filter id='MyFilter2' filterUnits='objectBoundingBox'
x='0' y='0' width='1' height='1'>
<feGaussianBlur in='SourceAlpha' stdDeviation='4%' result='blur'/>
<feOffset in='blur' dx='4%' dy='4%' result='offsetBlur'/>
<feSpecularLighting in='blur' surfaceScale='5' specularConstant='.75'
specularExponent='20' lighting-color='#bbbbbb' result='specOut'>
<fePointLight x='50%' y='50%' z='5000%'/>
</feSpecularLighting>
<feComposite in='specOut' in2='SourceAlpha'
operator='in' result='specOut'/>
<feComposite in='SourceGraphic' in2='specOut' operator='arithmetic'
k1='0' k2='1' k3='1' k4='0'/>
</filter>
</defs>
"""
tree, xmlid = ET.XMLID(f.getvalue())
tree.insert(0, ET.XML(filter_def))
for i, pie_name in enumerate(labels):
pie = xmlid[pie_name]
pie.set("filter", 'url(#MyFilter2)')
shadow = xmlid[pie_name + "_shadow"]
shadow.set("filter", 'url(#dropshadow)')
fn = "svg_filter_pie2.svg"
print(f"Saving '{fn}'")
ET.ElementTree(tree).write(fn)
まとめ
この実験では、Matplotlib の円グラフにフィルタリング効果を使う方法を学びました。円グラフを作成し、SVG ファイルとして保存し、そのグラフにフィルタリング効果を適用しました。また、異なる視覚的な効果を得るために、異なるフィルタを使って円グラフを変更しました。