Tutorialに学ぶseabornの使い方②(Plotting with categorical data)|Pythonによる可視化入門 #6

f:id:lib-arts:20190614213755p:plain
連載の経緯は#1をご確認ください。

#1〜#4まではMatplotlibに関して、#5ではseabornの概要と、チュートリアルの"Visualizing statistical relationships"を元に使い方についてまとめました。

#6では#5に引き続きseabornのチュートリアルから"Plotting with categorical data"について取り扱います。
以下目次になります。
1. Plotting with categorical dataについて
1-1. Categorical scatterplots
1-2. Distributions of observations within categories
1-3. Statistical estimation within categories
1-4. Plotting “wide-form” data(省略)
1-5. Showing multiple relationships with facets(省略)
2. まとめ


1. Plotting with categorical dataについて
1節ではチュートリアルの"Plotting with categorical data"について取り扱っていきます。

f:id:lib-arts:20190615171609p:plain

Plotting with categorical data — seaborn 0.9.0 documentation

まずは簡単な概要をつかめればということで、冒頭のみ和訳します。

In the relational plot tutorial we saw how to use different visual representations to show the relationship between multiple variables in a dataset. In the examples, we focused on cases where the main relationship was between two numerical variables. If one of the main variables is “categorical” (divided into discrete groups) it may be helpful to use a more specialized approach to visualization.

和訳:『"relational plot tutorial"では、データセットにおける多変量間の相関性について可視化するにあたって様々な視覚表現について確認してきました。サンプルコードにおいては2つの数値的なメイン変数間の相関を見ることにフォーカスをあてました。片方のメインの変数がカテゴリカル(離散的な変数の一種)だとすると、可視化にあたってより特化したアプローチを考えることができます。』
上記より、このチュートリアルページのメインテーマが、カテゴリカル変数の可視化にあることがわかります。説明が長くなると逆にわかりづらくなるので、詳細は1-1〜1-5で取り扱うとして、下記のコードの実行だけ行っていただき1-1節に移れればと思います。

import seaborn as sns
import matplotlib.pyplot as plt
sns.set(style="ticks", color_codes=True)


1-1. Categorical scatterplots
1-1ではカテゴリカル変数の散布図の作成を行う、"Categorical scatterplots"について取り扱います。まずは下記を実行してみましょう。

tips = sns.load_dataset("tips")
sns.catplot(x="day", y="total_bill", data=tips);

実行結果は下記のようになります。

f:id:lib-arts:20190615173312p:plain
通常の散布図であれば点を打つだけで良いものの、カテゴリカル変数の散布図については同じポイントの点の数を判断するのが難しいという問題がありますが、上図ではランダムのノイズ(random “jitter”)を加えることで同じ値の点の数も可視化できるようにされています。オプションjitterをFalseにすることで下記のようにすることもできますが、これだとやはりサンプルの数を判断するのが難しくなっています。

f:id:lib-arts:20190615174604p:plain
可視化にあたってのもう一つのアプローチとしては、"beeswarm"もあります。beeswarmはkind="swarm"を引数として与えることで実施することができます。可視化は下記のように行うことができます。

sns.catplot(x="day", y="total_bill", kind="swarm", data=tips);

f:id:lib-arts:20190615174626p:plain
このようにランダムノイズやbeeswarmを用いることで、カテゴリカル変数の散布図を描くことができます。


1-2. Distributions of observations within categories
1-2ではカテゴリカル変数の分布の作成を行う"Distributions of observations within categories"について取り扱います。可視化の目的は1-1と同じなのですが、アプローチが違うという認識が良いかと思います。まずは下記を実行してみましょう。

sns.catplot(x="day", y="total_bill", kind="box", data=tips);

f:id:lib-arts:20190615194712p:plain
上記ではkindに"box"を与えることで箱ひげ図(Boxplots)が描画されています。箱ひげ図以外にもkindに"violin"を与えることで、Violinplotsの作成を行うことができます。

sns.catplot(x="day", y="total_bill", hue="sex",
kind="violin", inner="stick", split=True,
palette="pastel", data=tips);

f:id:lib-arts:20190615194757p:plain

このように、分布を用いてカテゴリカル変数の可視化を行うことができます。


1-3. Statistical estimation within categories
1-3では統計的な推定についての描画を行う"Statistical estimation within categories"について取り扱います。まずは下記を実行してみましょう。

titanic = sns.load_dataset("titanic")
sns.catplot(x="sex", y="survived", hue="class", kind="bar", data=titanic);

f:id:lib-arts:20190615195615p:plain

データセットのTitanicはタイタニック号の乗客生存を表した有名なデータセットです。簡単に概要を確認すると下記のようになります。

print(type(titanic))
print(titanic.shape)
print(titanic.head())

f:id:lib-arts:20190615195650p:plain
確認すると、グラフのy軸の入力として与えているsurvivedは0/1の2値データとなっていることがわかります。kind="bar"とすることで、それぞれの生存確率の可視化を行っています。また、下記のようにすることでヒストグラムも描画することができます。

sns.catplot(x="deck", kind="count", palette="ch:.25", data=titanic);

f:id:lib-arts:20190615200231p:plain
このように、様々な統計的な推定量の可視化を行うことができます。


1-4. Plotting “wide-form” data
必要があれば後日追記します。


1-5. Showing multiple relationships with facets
必要があれば後日追記します。


2. まとめ
#6では"Plotting with categorical data"について取り扱いました。情報量が豊富なので、ところどころ飛ばしたり、1-4と1-5は省略しましたが、一通り基本的な内容については抑えられたかと思います。
#7では"isualizing the distribution of a dataset"について取り扱えればと思います。

PASCAL VOC①(概要&PASCAL VOC2007の確認)|機械学習の有名データセットや評価指標を確認する #1

f:id:lib-arts:20190621231512p:plain
機械学習の研究を読み解いたり実際に取り組んだりする中で、先に把握しておくと良いのが有名なデータセットやその評価指標などです。これらについて把握しておくことで、学習にあたっての目的が明確になったり、誤差関数を組むにあたっての参考になったりします。
また、どのようなデータセットでどのくらいの結果が出ているかを概ね把握しておくことで、取り組むタスクの難易度や予算感、マイルストーン設定なども明確になります。
このように、意外とデータセットや評価指標についてのポイントで詰まると時間が無駄になるので、それを受け当シリーズでは機械学習における有名なデータセットや評価指標についての確認を行なっていければと思います。
#1では2005年〜2012年頃の画像認識のデータセットとして有名なPASCAL VOCの概要と初期のデータセットとしてよく見かけるPASCAL VOC2007について取り扱います。
以下目次になります。
1. PASCAL VOCの概要
2. PASCAL VOC2007の概要
3. PASCAL VOC2007のデータセットやそれぞれの評価指標の確認
4. まとめ


1. PASCAL VOCの概要
1節ではPASCAL VOCの概要について取り扱います。まずは公式のトップページを確認します。

f:id:lib-arts:20190621232240p:plain

The PASCAL Visual Object Classes Homepage
PASCALは"Pattern Analysis, Statistical Modeling and Computational Learning"、VOCは"Visual Object Classes"を意味しています。概要を掴むにあたって上記を簡単に和訳します。

要約:
PASCAL VOCのプロジェクト
・物体クラス認識のためのスタンダードな画像のデータセットを提供します
・データセットアノテーションにアクセスするための一般的なツールセットを提供します
・結果の評価や異なる手法間の比較を可能にします
・パフォーマンスを評価するコンペティションを開催します(2005年〜2012年)

 

PASCAL VOCのデータセット
VOCのコンペティションのデータはリンクページから入手可能で、データセットに関する新規手法の評価は"PASCAL VOC Evaluation Server"から手に入れることができます。"evaluation server"はコンペティションが終了してもアクティブのまま残る予定です。

次にトップページの各年のコンペの詳細も簡単に見てみます。

f:id:lib-arts:20190622120829p:plain

f:id:lib-arts:20190622121139p:plain

2005年に始まり、2012年に終了しているのですが、ベンチマークとして時折見かける2007、2010、2012を中心に見ていきます。まずは2007年のところで20クラスの画像が用意されています。画像数はだいたい10,000ほどで、24,640の物体のアノテーションがあるとされています。2010年はNew developmentsのところでILSVRC(Imagenet Large Scale Visual Recognition Challenge)について言及されています。2012年は最終年ですが、画像やアノテートとしては一番多くなっています。
だいたいの概要はつかめたと思うので、2節、3節では上記を受けてPASCAL VOC2007について確認していきます。

 

2. PASCAL VOC2007の概要
2節ではPASCAL VOC2007の概要について見ていきます。まずは公式の2007年のページを確認します。

f:id:lib-arts:20190622122226p:plain

The PASCAL Visual Object Classes Challenge 2007 (VOC2007)

まずは概要について確認できればということでIntroductionを要約します。

f:id:lib-arts:20190622122502p:plain

要約:
このコンペティションの目的は多くの実際の画像(例えば事前に物体のセグメントなどがされていない画像)から物体を認識することです。基本的にはラベル付けされた画像の学習セットが与えられた状況での教師あり学習(supervised learning)の問題です。選ばれた20の物体のクラスは下記です。
・人:人
・動物:鳥、猫、牛、犬、馬、羊
・乗物:飛行機、自転車、ボート、バス、車、バイク、電車
・家具:ボトル、椅子、キッチンテーブル、ポット、ソファ、テレビ
二つの主要なコンペティションと、より小さな二つのお試し用の(taster)コンペティションがあります。

次にMain Competitionsについて確認していきます。こちらも簡単に要約します。

f:id:lib-arts:20190622123710p:plain

1. 画像分類:20クラスの画像それぞれに対して、テスト画像においてクラスが存在するか/しないかを予測する。
2. 物体検出:テスト画像の20クラスの対象からそれぞれの物体のbounding boxとラベルを予測する。
参加者はどちらか及び両方のコンペティションに参加でき、20クラスの中から任意の一つまたは全てのクラスに取り組むことができます。

また、Taster Competitionsについても確認していきましょう。こちらも簡単に要約します。

f:id:lib-arts:20190622124600p:plain

1. セグメンテーション:ピクセル単位のセグメンテーション(意味分割)を生成する。
2. Person Layout:頭や手、足など人の体の部位をbounding boxで予測する。

上記まででPASCAL VOC2007の概要については確認できたので、2節はここまでとできればと思います。
3節では実際にデータセットの中身を確認していきます。


3. PASCAL VOC2007のデータセットやそれぞれの評価指標の確認
3節ではPASCAL VOC2007のデータセットやそれぞれの評価指標について確認していきます。まずは"PASCAL VOC2007 Example Images"のページを確認します。

f:id:lib-arts:20190622125524p:plain

PASCAL VOC2007 Example Images

画像は少なくとも一つのインスタンスを含むとされています。リンクをクリックすることでそれぞれのサンプルについて確認することができます。以下いくつか例をご紹介します。
・鳥

f:id:lib-arts:20190622154847p:plain
・猫

f:id:lib-arts:20190622154910p:plain
・犬

f:id:lib-arts:20190622155137p:plain
飛行機

f:id:lib-arts:20190622155320p:plain
・ボート

f:id:lib-arts:20190622155357p:plain
・椅子

f:id:lib-arts:20190622155422p:plain
また評価指標については下記のスライドにまとまっています。

f:id:lib-arts:20190622160054p:plain

http://host.robots.ox.ac.uk/pascal/VOC/voc2007/workshop/everingham_cls.pdf

評価指標としては、物体検出の際などによく出てくるAverage Precisionが用いられています。


4. まとめ
#1ではPASCAL VOC 2007について取り扱いました。
#2も同様にPASCAL VOCから2010と2012について取り扱えればと思います。

Tutorialに学ぶseabornの使い方①(概要&Visualizing statistical relationships)|Pythonによる可視化入門 #5

f:id:lib-arts:20190614213755p:plain

連載の経緯は#1をご確認ください。

Pythonでの可視化について取り扱えればということで#1〜#4ではMatplotlibについてまとめました。

#4までで大体のMatplotlibの使い方については把握ができたので、#5からはMatplotlibベースで高度な描画を実現してくれるseabornについて取り扱っていきます。#5ではseabornの概要と、チュートリアルの"Visualizing statistical relationships"を元に使い方についてまとめていきます。
以下目次になります。
1. seabornの概要
2. Visualizing statistical relationshipsについて
2-1. Relating variables with scatter plots
2-2. Emphasizing continuity with line plots
2-3. Showing multiple relationships with facets
3. まとめ


1. seabornの概要
1節ではseabornの概要についてまとめていきます。

f:id:lib-arts:20190614221449p:plain

seaborn: statistical data visualization — seaborn 0.9.0 documentation

上記のseabordのドキュメントを元に解説を行っていきます。概要文がそれほど長くないので、簡単に和訳を行います。

Seaborn is a Python data visualization library based on matplotlib. It provides a high-level interface for drawing attractive and informative statistical graphics.
For a brief introduction to the ideas behind the library, you can read the introductory notes. Visit the installation page to see how you can download the package. You can browse the example gallery to see what you can do with seaborn, and then check out the tutorial and API reference to find out how.
To see the code or report a bug, please visit the github repository. General support issues are most at home on stackoverflow, where there is a seaborn tag.

和訳:『seabornはmatplotlibにベースとして用いたPythonでのデータ可視化ライブラリです。seabornのhigh-levelなインターフェースを用いることで見栄えがよくて有益な統計的なグラフを描くことができます。ライブラリの背後にある考え方を簡単に知るにあたっては、"introductory notes"が役に立ちます。また、パッケージのダウンロードの方法に関しては"installation page"を確認してください。"example gallery"を見ればseabornでできることを確認することができ、"tutorial"や"API reference"で詳細を確認することができます。コードを見たりバグの報告したりにあたっては、"github repository"にアクセスしてください。一般的なサポートについてはseabornのタグがついた"stackoverflow"を確認してください。』
matplotlibベースのライブラリであることから考えると、ベーシックな機能というよりはより可視化を意識したライブラリになっているようです。概要からリファレンス情報まで過不足なくまとまっているという意味で非常に読みやすいトップページの印象です。
大体のライブラリの概要はつかむことができたので2節では実際にチュートリアルを確認していきます。

f:id:lib-arts:20190614222140p:plain

Official seaborn tutorial — seaborn 0.9.0 documentation

上記でチュートリアルがまとまっているのですが、全て取り扱うと長くなりそうなので#5では"Visualizing statistical relationships"について取り扱っていきます。


2. Visualizing statistical relationshipsについて
2節ではチュートリアルより、"Visualizing statistical relationships"について取り扱っていきます。

f:id:lib-arts:20190614231448p:plain

Visualizing statistical relationships — seaborn 0.9.0 documentation

まず簡単な概要をつかめればということで冒頭のみ和訳します。

Statistical analysis is a process of understanding how variables in a dataset relate to each other and how those relationships depend on other variables. Visualization can be a core component of this process because, when data are visualized properly, the human visual system can see trends and patterns that indicate a relationship.

和訳:『統計的な分析は、データセットの変数がどのように相互で関係しているかや他の変数とどのように依存関係にあるかを理解するプロセスです。可視化はこのプロセスの主要な要素であり、理由としてはデータが適切に可視化されるならば人間の視覚が関連性を指摘するトレンドやパターンを認識することができるからです。』
上記から読み取るに、統計的な分析において変数間の関係性について議論するにあたって可視化が重要であり、それについてseabornで実現していくという流れになっているようです。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style="darkgrid")

また、上記を先に実行しておく必要があるので、2-1以降に進む前にこちらを先に実行しておいてください。


2-1. Relating variables with scatter plots
2-1では相関性のある変数の散布図を描画する"Relating variables with scatter plots"について取り扱います。まずは下記を実行してみましょう。

tips = sns.load_dataset("tips")
sns.relplot(x="total_bill", y="tip", data=tips);

実行結果は下記のようになります。

f:id:lib-arts:20190614232210p:plain
Matplotlibの図の時と同様に散布図の描画になっていますが、より洗練されたデザインになっています。
大体のイメージがつかめたところで気になるのは分析対象のデータです。分析対象のデータはtipsで与えられているので、tipsの中身について把握を行います。

print(type(tips))
print(tips.shape)
print(tips.head(10))

上記を実行すると下記のように、データの形式やサイズの把握を行うことができます。

f:id:lib-arts:20190614234224p:plain
こちらを確認することで、サイズが(244, 7)のPandasの形式でデータが得られていることがわかります。また、sns.replotの引数に与えた"total_bill"と"tip"は列の名前であるということがわかります。ここで7次元あるデータのうち2次元しか使っていないのですが、seabornではもう少し図に情報量を増やすことができます。

sns.relplot(x="total_bill", y="tip", hue="smoker", style="time", data=tips);

上記を実行することで下記のような図が得られます。

f:id:lib-arts:20190614234333p:plain
これは4つの変数を考慮しているので、実質4次元で可視化が行えているということになります。
またさらに定量的な軸を足すにあたっては、sizeという引数を用いることで大きさを変えることも可能です。

sns.relplot(x="total_bill", y="tip", size="size", sizes=(15, 200), data=tips);

上記を実行すると下記のようになります。

f:id:lib-arts:20190614234651p:plain
このように単なる相関性の可視化であっても、seabornを用いることで非常に自由度の高い形で描画を行うことができます。


2-2. Emphasizing continuity with line plots
2-2では主に時系列データに適用できそうな"Emphasizing continuity with line plots"についてご紹介します。まずは下記を実行してみましょう。

df = pd.DataFrame(dict(time=np.arange(500),
value=np.random.randn(500).cumsum()))
g = sns.relplot(x="time", y="value", kind="line", data=df)
g.fig.autofmt_xdate()

f:id:lib-arts:20190615000039p:plain
上記はランダムウォークのような過程を図示したものです。観測対象が乱数を用いて生成されているので、実行するごとに違うデータになることに注意です(np.random.seedで乱数を固定すれば同じ結果を得られるようにすることができます)。与える引数のkindに"line"を設定することで時系列データを表現してくれていることに注意です。kindをデフォルトにすると散布図の形式になるので、下記も実行して比較を行ってみてください。

df = pd.DataFrame(dict(time=np.arange(500),
value=np.random.randn(500).cumsum()))
g = sns.relplot(x="time", y="value", data=df)
g.fig.autofmt_xdate()

f:id:lib-arts:20190615000154p:plain
このようにkindに何も与えなければ散布図に変わります。
もう一例確認できればということで、下記を実行してみてください。

fmri = sns.load_dataset("fmri")
sns.relplot(x="timepoint", y="signal", kind="line", data=fmri);

f:id:lib-arts:20190615000840p:plain
通常の折れ線グラフに加え、y軸に区間の情報が入っています。2-1の際と同様に対象データの中身をつかめればということで、下記を実行してみてください。

print(type(fmri))
print(fmri.shape)
print(fmri.head(15))

f:id:lib-arts:20190615001739p:plain
実行結果を見ると、timepointがユニークではなく、複数あることがわかります。y軸の区間はそれぞれのtimepointにおける平均の値と95%信頼区間の可視化を行っています。このように計測データが複数ある際の時系列データも可視化を行うことができます。ちなみにci=Noneを設定することで(ci; confidence interval)、信頼区間を省略することもできます。

sns.relplot(x="timepoint", y="signal", ci=None, kind="line", data=fmri);

f:id:lib-arts:20190615001805p:plain
時系列のグラフについても大体の概要がつかめたので、2-2はここまでとします。


2-3. Showing multiple relationships with facets
2-3ではグラフの描き分けに関しての"Showing multiple relationships with facets"について取り扱っていきます。まずは下記のコードを実行してみましょう。

sns.relplot(x="total_bill", y="tip", hue="smoker", col="time", data=tips);

f:id:lib-arts:20190615002216p:plain
生成された図を見ることで、colで与えた"time"の情報を元にLunchとDinnerでグラフを描き分けてくれていることがわかります。
もう一例確認できればということで、fmriデータについても見てみましょう。下記を実行してみてください。

sns.relplot(x="timepoint", y="signal", hue="subject",
            col="region", row="event", height=3,
            kind="line", estimator=None, data=fmri);

f:id:lib-arts:20190615002647p:plain
上記を確認することによって、列方向にはregion、行方向にはeventでグラフが描き分けられていることがわかります。
この辺のグラフの描き分けを実装するとなると少し厄介なので、なかなか便利な機能だと思われます。


3. まとめ
#5ではseabornの概要と、"Visualizing statistical relationships"の内容について抜粋してご紹介しました。

Visualizing statistical relationships — seaborn 0.9.0 documentation

チュートリアルが非常に充実しており、全て取り扱うと冗長になると思われ半分ほどのご紹介となりましたので、より詳しくは上記をご確認いただけたらと思います。
#6でも引き続きseabornチュートリアルから"Plotting with categorical data"を取り扱えればと思います。

Matplotlibの使い方④(plt.subplots、plt.title、plt.legend)|Pythonによる可視化入門 #4

f:id:lib-arts:20190611223958p:plain

#1では連載の経緯と、よく使う可視化機能であるmatplotlib.pyplotより、plt.plot、plt.scatter、plt.histについてまとめました。

また、#2では"Sample plots in Matplotlib"より、plt.bar、plt.pie、plt.hist2dについて、#3では少々発展的なグラフの描画として、plt.streamplot、plt.fill、plt.polarをご紹介しました。

#4ではグラフの描画にあたって知っておきたい内容として、plt.subplots、plt.title、plt.legendについて取り扱います。
以下目次になります。
1. グラフの描画にあたって知っておきたい機能(plt.subplots、plt.title、plt.legend)
1-1. plt.subplotsを用いた複数グラフの描画
1-2. plt.title、plt.xlabel、plt.ylabelを用いたタイトルや軸のラベル付け
1-3. plt.legendを用いた説明書き(凡例)の追加
2. まとめ


1. グラフの描画にあたって知っておきたい機能(plt.subplots、plt.title、plt.legend)
#4はグラフをカスタマイズしていくにあたって知っておきたい機能として、plt.subplots、plt.title、plt.legendなどについて取り扱っていきます。

 

1-1. plt.subplotsを用いた複数グラフの描画
1-1ではplt.subplotsを用いて複数グラフの描画を行っていきます。

f:id:lib-arts:20190614200141p:plain

Sample plots in Matplotlib — Matplotlib 3.1.0 documentation

plt.subplotsは上記のページでも最下部で触れられています。説明から入ると大変なので、まずはコードを先に動かします。下記のコードを実行して見てください。

import matplotlib.pyplot as plt
import numpy as np

np.random.seed(19680801)
data = np.random.randn(2, 100)

fig, axs = plt.subplots(2, 2, figsize=(5, 5))
axs[0, 0].hist(data[0])
axs[1, 0].scatter(data[0], data[1])
axs[0, 1].plot(data[0], data[1])
axs[1, 1].hist2d(data[0], data[1])

plt.show()

結果は下記のようになります。

f:id:lib-arts:20190614200213p:plain
4つのグラフを同時に出力できていることがわかります。axsのインデックスで図表を管理していそうというのがここから読み取れます。とはいえこれだけだと使いこなすまで至らないため、plt.subplotsのドキュメントを確認していきましょう。

f:id:lib-arts:20190614201223p:plain
(中略)

f:id:lib-arts:20190614201428p:plain
上記を確認する際にまず気になるのが値指定が必須の引数です。必須の引数としてはnrowsとncolsで、"Number of rows/columns of the subplot grid."とあるので、サブプロットグリッド(描画するグラフを格子状に配置したもの)の行数と列数を表すとあります。次に気になるのが返り値です。二つ目の返り値を用いてグラフを描画しているので、axに着目しましょう。AxesオブジェクトもしくはAxesオブジェクトの配列を生成しているとあるのですが、深入りすると大変そうなので、一旦Axesオブジェクトというものがあるという認識にしておきます。
例が二つある方が比較できて良いので、もう一例ご紹介します。

Plotting categorical variables — Matplotlib 3.1.0 documentation

より、サンプルコードを拝借します。

import matplotlib.pyplot as plt

data = {'apples': 10, 'oranges': 15, 'lemons': 5, 'limes': 20}
names = list(data.keys())
values = list(data.values())

fig, axs = plt.subplots(1, 3, figsize=(9, 3), sharey=True)
axs[0].bar(names, values)
axs[1].scatter(names, values)
axs[2].plot(names, values)
fig.suptitle('Categorical Plotting')

上記の実行結果は下記になります。

f:id:lib-arts:20190614202836p:plain

1行3列でグラフが描画できていることが上記より確認できます。
このようにplt.subplotsを用いることで、複数グラフの描画を行うことができます。

 

1-2. plt.title、plt.xlabel、plt.ylabelを用いたタイトルや軸のラベル付け
1-2ではタイトルや軸のラベル付けを行うにあたって、plt.title、plt.xlabel、plt.ylabelをご紹介します。

f:id:lib-arts:20190614203617p:plain

Usage Guide — Matplotlib 3.1.0 documentation

まずは上記のコードを動かしてみます。

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2, 100)

plt.plot(x, x, label='linear')
plt.plot(x, x**2, label='quadratic')
plt.plot(x, x**3, label='cubic')

plt.xlabel('x label')
plt.ylabel('y label')

plt.title("Simple Plot")

plt.legend()

plt.show()

上記の実行結果は下記のようになります。

f:id:lib-arts:20190614203853p:plain

実行結果とソースを見比べると、plt.xlabelでx軸のラベル、plt.ylabelでy軸のラベル、plt.titleで図表のタイトルを記述しているということがわかります。

挙動を確認するにあたって、少しだけそれぞれ修正を行ってみます。

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2, 100)

plt.plot(x, x, label='linear')
plt.plot(x, x**2, label='quadratic')
plt.plot(x, x**3, label='cubic')

plt.xlabel('x label modified')
plt.ylabel('y label modified')

plt.title("Simple Plot(modified title)")

plt.legend()

plt.show()

実行結果は下記のようになります。

f:id:lib-arts:20190614204157p:plain
それぞれの変更が反映されていることが確認できます。

 

1-3. plt.legendを用いた説明書き(凡例)の追加
1-2の例でplt.legendも出ていたので、同じ例を用いて解説を行います。まずはplt.legend()をコメントアウトして実行してみましょう。

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2, 100)

plt.plot(x, x, label='linear')
plt.plot(x, x**2, label='quadratic')
plt.plot(x, x**3, label='cubic')

plt.xlabel('x label')
plt.ylabel('y label')

plt.title("Simple Plot")

#plt.legend()

plt.show()

 実行結果は下記のようになります。

f:id:lib-arts:20190614205507p:plain
1-2で出ていたグラフに関する注釈が消えていることがわかります。

f:id:lib-arts:20190614205651p:plain

matplotlib.pyplot.legend — Matplotlib 3.1.0 documentation
上記で簡単な言及がされているのですが、ドキュメントのコードと概ね同様の記述がされているようです。
もう一例ある方が良さそうなので例をもう一つ追加させていただきます。

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2, 100)

plt.plot(x, x, label='linear modified')
plt.plot(x, x**2)
plt.plot(x, x**3, label='cubic modified')

plt.xlabel('x label')
plt.ylabel('y label')

plt.title("Simple Plot")

plt.legend()

plt.show()

実行結果は下記のようになります。

f:id:lib-arts:20190614205951p:plain
y=xy=x^3のグラフの凡例は変更され、y=x^2のグラフの凡例は消去されていることが確認できます。


2. まとめ
#4ではグラフのカスタマイズにあたって知っておきたい内容として、plt.subplots、plt.title、plt.legendについて取り扱いました。
ここまでで、Matplotlibの大まかな使い方は把握ができたので、#5では他の描画ライブラリとしてseabornについて取り扱っていきます。

概論&全体的な研究トレンドの概観③(FPN、RetinaNet、M2Det)|物体検出(Object Detection)の研究トレンドを俯瞰する #3

f:id:lib-arts:20190618232406p:plain

物体検出の研究については以前に論文読解で、FasterRCNNやYOLO、SSD、RetinaNetについて取り扱ったのですが、改めて研究トレンドや考え方の推移についてまとめられればということで新規でシリーズを作成させていただきました。
#1ではHOG(Histograms of Oriented Gradient)[2005]からR-CNN[2013]までについて、#2ではFast R-CNN、FasterRCNN、YOLO、SSDについて取り扱いました。

#3では2016年以降の取り組みとして、FPN、RetinaNet、M2Detについてまとめていきます。
以下目次になります。
1. Feature Pyramid Networks[2016]
2. RetinaNet[2017]とFocal Loss
3. M2Det[2018]とMulti-Level Feature Pyramid Network
4. まとめ


1. Feature Pyramid Networks[2016]
1節では2016年12月の研究である"Feature Pyramid Networks for Object Detection"[2016]について取り扱います。

f:id:lib-arts:20190618233856p:plain

[1612.03144] Feature Pyramid Networks for Object Detection

R-CNNやFaster R-CNNのAuthorである、Ross Girshick氏が関わっている研究で、全体の研究トレンドに影響を与えているであろうことも伺えます。概要を掴むにあたって、まずは簡単にAbstractを要約します。

f:id:lib-arts:20190618234426p:plain
要約:『ピラミッド型の特徴量の利用(Feature pyramids)はスケールの違う物体の検出における認識システムの基本的な構成要素である一方で、Deep Learningの物体検出器は計算量やメモリ消費などの理由でpyramid型の表現は避けてきた。この論文においてはこれまでのDeepLearningの検出器に反してmulti-scaleでピラミッド型の特徴量の階層を用いており、この構造をFeature Pyramid Network(FPN)と呼ぶ。FPNをベーシックなFaster R-CNNのシステムに用いることでCOCOのdetection benchmarkでSOTAを実現した。それに加えてGPUで6FPSを実現し、マルチスケールを用いた物体検出の実用的な実現方法として示すことができた。』
上記で大体の概要を掴むことができます。物体の検出にあたってはマルチスケールのFeatureを用いることが昔からあった一方で、DeepLearningではなかなかそれを組み込めないでいたところに対して、Feature Pyramid Networkを提案したというのが主な論旨になります。Feature Pyramid Networkとその他のDeepLearningの手法との比較については、下記のFigure1に詳しくまとまっています。

f:id:lib-arts:20190619000603p:plain

(a)~(d)をそれぞれ見た際に、(a)は遅い、(b)と(c)は(b)はFast R-CNNやFaster R-CNNで用いられ、(c)はSSD(Single Shot Detector)で用いられています。(d)は(b)や(c)のように速い一方でより正確だとされています。また、この図において青い枠(blue outlines)で囲ったところがfeature mapsだとされており、太い線(thicker outline)は意味的に強い特徴量であるということを示しています。
詳細の処理についてはSection3でFeature Pyramid Networksの詳細についてまとまっており、"Bottom-up pathway"で"backbone ConvNet"とあるようにVGGやResNetなどのベースのCNNのアーキテクチャを示唆しています。また"Top-down pathway and lateral connections."でupsamplingについての話がまとまっています。"spatially coarser, but semantically stronger(空間的には疎だけれど、意味的には強い)"と表現されているのがなかなか興味深いところです。

f:id:lib-arts:20190619002709p:plain
Upsamplingに関してはFigure3でも図示されています。


2. RetinaNet[2017]とFocal Loss
2節では2017年8月の研究である"Focal Loss for Dense Object Detection(RetinaNet)"について取り扱います。

f:id:lib-arts:20190619004023p:plain

[1708.02002] Focal Loss for Dense Object Detection

こちらもRoss Girshick氏がAuthorになっているのと、SPPNetのFirst AuthorのKaiming He氏もAuthorになっています。概要を掴むにあたって、Abstractを簡単に要約していきます。

f:id:lib-arts:20190619004414p:plain
要約:『近年の最も高い精度を出している物体検出器(object detectors)はR-CNNに代表されるtwo-stageのアプローチで、分類器が物体の候補領域の疎な集合に適用される。それに比較してone-stageの検出器はより速くシンプルであるというポテンシャルを持つ一方で精度の面ではtwo-stageの検出器の後追いになってしまっている。我々はその理由としてのclass imbalanceに着目し、標準のクロスエントロピー誤差をカスタマイズすることで問題に取り組んだ。この新しいFocal Lossは膨大な数のeasy negativesが誤差関数を圧迫することを防いでくれる。このFocal Lossを導入したシンプルな検出器を我々はRetinaNetと名付けた。Focal Lossを導入することでSOTAのtwo-stageの検出器の精度を上回りつつ、one-stage検出器のスピードを実現した。
one-stageの検出器の問題に取り組んだとあり、その点を意識しながら新しく導入したFocal LossとRetinaNetについて確認していくと良さそうです。

f:id:lib-arts:20190619010337p:plain

(中略)

f:id:lib-arts:20190619010357p:plain
Focal LossについてはSection3のFocal Lossで解説されています。(2)でp_{t}の定義が正解した(物体を物体とあてるに加えて背景を背景とあてるのも正解となるようにされています)際の確信度に実質なるように定義していることに注意です。通常のクロスエントロピー(cross-entropy)誤差関数がCE(p,y)=CE(p_{t})=-log(p_{t})で定義されている一方で、Focal LossではFL(p_{t})=-(1-p_{t})^{\gamma}log(p_{t})という風に定義されています。ここで新しく付け加わった(1-p_{t})^{\gamma}に着目します。\gammaの定義域としては論文内で\gamma \in [0,5]とされているのでこの範囲について考えます。まず\gamma=0のとき、全てのp_{t}に関して(1-p_{t})^0=1となるのでFocal LossはCross Entropyに一致します。また、\gamma=1のとき、(1-p_{t})^1=-p_{t}+1となるので、y=-x+1のような直線で表すことができます。同様に\gamma=5まで考えると長くなるので、下記で可視化してみました。

f:id:lib-arts:20190619152652p:plain
注目は\gammaの値が大きくなればなるほど、p_{t}の値が1に近づくにつれて小さい倍率がかかるということです。

f:id:lib-arts:20190619153050p:plain
論文内で上記のように具体的な値を出して説明しており、デフォルトで用いられている\gamma=2において簡単に計算してみると下記のようになります。

f:id:lib-arts:20190619153110p:plain

このようにFocal Lossはうまく分類できている(p_{t})の値が大きいケースに大きな補正がかかるようになっています。一方で、言及があるように、p_{t}が0.5より小さいケースでは最大でも補正は4倍であり、0.9の値とは大きな違いを見せています。

f:id:lib-arts:20190619153925p:plain
補正項を誤差関数に組み込むことによって、上記のFigure1で示されたようなクロスエントロピーの補正が行われています。
また、このFocal Lossを組み込んだRetinaNetについてはSection4で記載されており、ネットワークのアーキテクチャとしては1節でまとめたFeature Pyramid Networksが用いられています。

f:id:lib-arts:20190619154432p:plain


3. M2Det[2018]とMulti-Level Feature Pyramid Network
3節では2018年11月のAlibaba Groupなどが行なった研究である"M2Det: A Single-Shot Object Detector based on Multi-Level Feature Pyramid Network"についてご紹介します。

f:id:lib-arts:20190619155058p:plain

[1811.04533] M2Det: A Single-Shot Object Detector based on Multi-Level Feature Pyramid Network

f:id:lib-arts:20190619155304p:plain
上図のようにスピード面と精度面の両方で高いパフォーマンスが実現されています。まずは概要を掴むにあたってAbstractを要約していきます。

f:id:lib-arts:20190619155336p:plain
要約:『Feature pyramidsは物体間でを通したスケールの違いのために生じる問題に取り組むために、SOTAのレベルでone-stage(DSSD,RetinaNet,RefineNet)、two-stage(Mask R-CNN,DetNet)の双方の検出器で広く用いられている。このFeature Pyramidsの構造は頼もしい成果を出している一方で、マルチスケールの計算の箇所が一つしかないことで限界を生じさせていると思われる。そこで新しくM2Detの研究では、Multi-LevelのFeature Pyramid Network(MLFPN)を提案する。MLFPNではThinned U-shape Modules(TUM)や、Feature Fusion Module(FFM)などのモジュールを用いている。このMLFPNの効率性を評価するために我々はSSDにMLFPNを組み込むことでend-to-endのパワフルなone-stageの検出器であるM2Detを提案し、SOTAのone-stage検出器の精度を上回った。』
上記が簡単な要約になります。RetinaNetの際のone-stageとtwo-stageの議論やFeature Pyramid Network(FPN)の構造を受け継いだ上で、FPNの構造をMulti-Levelにしたというのが注目のポイントです。したがって、MLFPNにおけるMulti-Levelの部分が一番気になる部分であり、以下そちらを確認していければと思います。

f:id:lib-arts:20190619161240p:plain
MLFPN(Multi-level Feature Pyramid Network)の概要については上記のFigure2でまとまっています。まず、入力画像をVGGやResNetのようなbackboneのネットワークで処理したのちにFFMv1を用いて混ぜ合わせ、ベースの特徴量(base feature)を作成しています。次にこのBase featureを入力としてTUM(Thinned U-shape Modules)を用いてmulti-scaleの特徴量のグループを生成しています。またこのアウトプットをFFMv2で混ぜ合わせmulti-scaleだけでなくmulti-levelも実現したとされています。multi-levelにおけるlevelはここでは層の深さを表しており、それぞれ図ではshallow、medium、deepとされています。最後にSFAM(Scale-wise Feature Aggregation)を用いてMulti-Level Feature Pyramidを作成しているとされています。
また、FFM、TUM、SFAMのそれぞれのモジュールの処理については、Figure4とFigure3でそれぞれ図解されています。
・FFMv1、FFMv2、TUM

f:id:lib-arts:20190619162713p:plain
・SFAM

f:id:lib-arts:20190619162732p:plain


4. まとめ
#3では2016年後半以後の話題として、FPN、RetinaNet、M2Detなどについて取り扱いました。
ここまでで大体の研究トレンドの俯瞰はできたので、#4以降では論文や実装の詳細を元にそれぞれをより詳しく取り扱っていければと思います。

 

↓下記でテキスト化していますので、よろしければこちらもご検討ください!!

概論&全体的な研究トレンドの概観②(FastRCNN、FasterRCNN、YOLO、SSD)|物体検出(Object Detection)の研究トレンドを俯瞰する #2

f:id:lib-arts:20190307173555p:plain

物体検出の研究については以前に論文読解で、FasterRCNNやYOLO、SSD、RetinaNetについて取り扱ったのですが、改めて研究トレンドや考え方の推移についてまとめられればということで新規でシリーズを作成させていただきました。
#1ではHOG(Histograms of Oriented Gradient)[2005]からR-CNN[2013]までについて取り扱いました。

#2ではFastRCNN、FasterRCNN、YOLO、SSDなどの2015〜2016年にかけての高速化と精度向上の両側面からの取り組みについてまとめていきます。
以下目次になります。
1. Fast R-CNN[2015]とRoI pooling
2. Faster R-CNN[2015]とRegion Proposal Networks
3. One stage detectorとYOLO[2015]
4. SSD
5. まとめ


1. Fast R-CNN[2015]とRoI pooling
1節ではFast R-CNNについて取り扱います。

f:id:lib-arts:20190618140925p:plain

[1504.08083] Fast R-CNN
まずは概要をつかむにあたってAbstractから確認します。簡単な和訳を行います。

f:id:lib-arts:20190618141143p:plain
和訳:『この論文はObject Detectionタスクに関して、Fast R-CNN(Fast Region-based Convolutional Network method)について提案する。Fast R-CNNはDeepなCNNを用いて物体の候補領域を効率的に分類する。従来の研究と比較すると、Fast R-CNNは精度を向上させながら学習と検証のスピードを改善させるいくつかの工夫を採用している。Fast R-CNNはR-CNNよりも学習時で9倍、推論時で213倍のスピードとなっている。また同時に、PASCAL VOC2012でより高いmAPを達成している。(以下略)』
後ろの方は概要をつかむにあたってそれほど重要には見えないので省略しました。要は#1でまとめたR-CNNの精度とスピードを候補領域の分類を効率よく行うことで向上させたというのがメイントピックで、和訳では略しましたが2014年のSPPnetよりも向上させたとあります。
ネットワークアーキテクチャ自体はSPP-Net[2014]を参考にしているところが多いようなので、SPP-NetのSpatial Pyramid Poolingを先に説明します。

f:id:lib-arts:20190618153838p:plain

[1406.4729] Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition

Spatial Pyramid Poolingについては論文のFigure3で概要が記述されています。こちらのPoolingを採用する利点としては、入力画像を固定長にしなくても良いというのがあります。入力画像を固定長にしなくてはならない理由としては最後のFC(Fully Connected)層を固定長にするためであり、畳み込みの処理には関係がないのでFC層の入力を作成するにあたってSpatial Pyramid Poolingを行うとあります。

f:id:lib-arts:20190618155525p:plain

この考え方をSection4のFigure5で物体検出(Object Detection)に導入しています。4.1で"We use the “fast” mode of selective search to generate about 2,000 candidate windows per image."とあるように、Selective Searchを用いて生成した候補領域に対してSpatial Pyramid Poolingを用いることで、R-CNNにおいて候補領域ごとにCNNを全て回していたのを畳み込み処理部分を一度で済ますことができるようになり処理速度を大きく向上させています。

f:id:lib-arts:20190618155556p:plain

Fast R-CNNのRoI poolingは上記のようにSpatial Pyramid Poolingの特殊なケースだというように書かれています。このように、R-CNNにおいてネックだった処理速度をFeature mapを計算するまでの畳み込み部分の処理を一度にまとめることで高速化をはかったというのがこれまでの流れになっています。


2. Faster R-CNN[2015]とRegion Proposal Networks
2節ではFaster R-CNN[2015]について取り扱います。Faster R-CNNはR-CNN、Fast R-CNNと同様にRoss Girshick氏がAuthorの一人となっています。まずはAbstractを簡単に要約します。

f:id:lib-arts:20190618160353p:plain

[1506.01497] Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks

要約:『SPPnetやFast R-CNNなどの研究を通して物体検出に用いるネットワークの大幅な時間短縮に繋がったが、一方で領域提案(region proposal)部分の処理がボトルネックとなった。そのため、領域提案ネットワーク(RPN; Region Proposal Network)を導入し、一つのネットワークに統合した。PASCAL VOCやMS COCOなどのデータセットにおいてSOTAを達成すると同時に高速化にも成功しGPUで5fps(frame per second)を実現した。』
上記で大体の概要がつかめるかと思います。少々補足すると、RPN(Region Proposal Network)が論文のメインのContributionで、Selective Searchなどを用いて候補領域を作成していたところもニューラルネットワークを用いて作成できるようにすることで、処理速度の向上が実現されています。また、PASCAL VOCは従来から用いられていたデータセットで、MS COCOも論文と同時期に整備されたデータセットです。
以下RPNについて説明を行なっていきます。

f:id:lib-arts:20190618162526p:plain

RPNについてはSection3のFigure2で言及されています。RoI poolingについては1節のFast R-CNNで言及した通りなので、ここでは省略します。RPNについては3.1でまとめられています。

f:id:lib-arts:20190618165152p:plain
RPNの処理については上記で記載されています。VGGやZFのような当時のオーソドックスなモデルを用いて作成したfeature mapに畳み込み処理を行うことで、cls層とreg層を出力しています。このcls層は物体かどうかの情報、reg層はbounding boxの座標の情報を表しています。一点、ここで注意なのがAnchorsについてです。通常の処理だけで計算したreg層で十分なのではと一瞬考えてしまいますが、Anchorの情報も付加することでスケールやアスペクト比の情報も加味した上で計算を行うことが可能になります。


3. One stage detectorとYOLO[2015]
3節ではYOLO(You Look Only Once)について取り扱います。YOLOはRetinaNet[2017]でも触れられているように、One stage detectorの初期のモデルと考えることができます。One stageとTwo stageの違いについては、領域提案部分が分離されているかされていないかの違いとして捉えられます。これまで取り扱ってきた、R-CNN、SPPnet、Fast R-CNN、Faster R-CNNはどれも領域提案部分がCNNを使おうが使うまいが独立していたのに対し、One stageでは処理が一度で済むような計算となっています。Abstractを軽く要約しておきます。

f:id:lib-arts:20190618170330p:plain

[1506.01497] Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks

要約:『YOLOでは従来の手法と異なり、物体検出の問題を回帰問題に変換した。推論時に一つのニューラルネットワークがbounding boxとクラスの確率を画像全体の入力から直接生成し、end-to-endで最適化を行なっている。また、YOLOのベースのモデルは統合された構造を用いた推論は極めて早く、45fpsのリアルタイムでの処理が可能となっている。また、Fast YOLOを用いると155fpsを実現した。』
上記のように、YOLOを見る際に一番衝撃なのが処理速度です。大幅な高速化がはかられたFaster R-CNNでさえ、5fpsのところをそれよりもはるかに速い処理を実現しています。

全体の処理については上記のSection2の説明のところでも言及しましたので一部抜粋します。
『画像の全体をS×Sのグリッドで考え、バウンディングBOXの抽出とグリッドのクラスの確率の予測を別々に行い、それを組み合わせて推論結果を出しています。話がやや抽象的でややこしいのでYOLOをPASCAL VOCを用いて評価する話をベースに具体化すると、グリッドをS=7、グリッド単位でのバウンディングBOXの候補数をB=2、クラスのラベル数をC=20とすることで、最終的な予測が7×7×30になるとされています。ここでBに5がかかっているのはバウンディングBOXの中心座標とサイズを表す(x,y,w,h)とバウンディングBOXの確信度を表すconfidenceで5個の値を持つためです。』
上記によって、S×S×(B*5+C)の意味がわかれば処理概要について把握することができます。
YOLOがそのあとの研究に与えた影響としては、One stageの考え方を導入しリアルタイムな物体検出を実現したというのが大きいように思われます。


4. SSD
SSD(Single Shot Detector)[2015]はYOLOと同じくOne stageのネットワークです。

f:id:lib-arts:20190618174811p:plain

https://arxiv.org/abs/1512.1506.02640
SSDは上図のように"Multi-scale feature maps"を用いて様々なスケールのfeature mapを用いて計算が行われています。

f:id:lib-arts:20190619164006p:plain
また、上記で触れられているようにAnchorの情報を元に作成したデフォルトボックス(default box)に推論結果のオフセット(offset)を適用することで、座標の調整(adjustment)を行なっています。2.1節に"Our default boxes are similar to the anchor boxes used in Faster R-CNN"とあるようにanchorの設定にあたっては基本的にはFaster R-CNNと同様に行なったとありますが、Faster R-CNNにあまり言及がなかったdefault boxやoffsetの話について丁寧に書かれています。


5. まとめ
#2では2015年〜2016年にかけて(SSDは2015/12にarxivにあがっているので、2016年とも考えられそう)の物体検出系の研究として、Fast R-CNN、Faster R-CNN、YOLO、SSDについてまとめました。
#3では2016年以降の話題として、Feature Pyramid Network[2016/12]、RetinaNet[2017]、M2Det[2018]について取り扱います。

Matplotlibの使い方③(plt.streamplot、plt.fill、plt.polar)|Pythonによる可視化入門 #3

f:id:lib-arts:20190611223958p:plain

#1では連載の経緯と、よく使う可視化機能であるmatplotlib.pyplotより、plt.plot、plt.scatter、plt.histについてまとめました。

また、#2では"Sample plots in Matplotlib"より、plt.bar、plt.pie、plt.hist2dをご紹介しました。

#3では少々発展的なグラフの描画として、plt.streamplot、plt.fill、plt.polarについて取り扱います。
以下目次になります。
1. 発展的なグラフの描画機能(plt.streamplot、plt.fill、plt.polar)
1-1. plt.streamplotを用いたベクトル場の描画
1-2. plt.fillを用いた曲線や多角形の色付けの描画
1-3. plt.polarを用いた極座標の描画
2. まとめ

 

1. 発展的なグラフの描画機能(plt.streamplot、plt.fill、plt.polar)
#3では少々発展的なグラフの描画ということで、plt.streamplot、plt.fill、plt.polarの三つについて取り扱っていきます。


1-1. plt.streamplotを用いたベクトル場の描画
1-1ではplt.streamplotを用いたベクトル場の描画を行います。

matplotlib.pyplot.streamplot — Matplotlib 3.1.0 documentation

Streamplot — Matplotlib 3.1.0 documentation
上記にドキュメントとサンプルコードがあるので参考にします。

詳細の確認から入るとわかりづらいので、サンプルコードを簡易化したコードをまず動かしてみます。

import numpy as np
import matplotlib.pyplot as plt

w = 3
Y, X = np.mgrid[-w:w:100j, -w:w:100j]
U = -1 - X**2 + Y
V = 1 + X - Y**2

# Varying density along a streamline
plt.streamplot(X, Y, U, V, density=[0.5, 1])

plt.show()

上記を動かした結果が下記になります。

f:id:lib-arts:20190614163257p:plain
plt.streamplotに引数を与えて実行することで、ベクトル場(vector field)の描画を行っています。与えている引数を先に確認する方が良さそうなので、下記のようにshapeメソッドを用いて行列のサイズを確認します。

f:id:lib-arts:20190614163339p:plain
上記より、100×100となっていることがわかります。また、Xの2行目と2列目を出力すると下記のようになります。

f:id:lib-arts:20190614163358p:plain
np.mgridを用いることでX方向には値が変化し、Y方向には値が変化しないような行列になっていることがわかります。ちなみにYはこの反対になっています。また、UとVについてはそれぞれの座標でのX値とY値から速度を計算しています。

f:id:lib-arts:20190614163559p:plain
上記のplt.streamplotのドキュメントによると、Uはx方向の速度、Vはy方向の速度となっています。

一例だけだとわかりづらいので、ベクトルの色の変化も加えたもう一例もご紹介します。

import numpy as np
import matplotlib.pyplot as plt

w = 3
Y, X = np.mgrid[-w:w:100j, -w:w:100j]
U = -1 - X**2 + Y
V = 1 + X - Y**2
speed = np.sqrt(U**2 + V**2)

# Varying color along a streamline
strm = plt.streamplot(X, Y, U, V, color=speed, linewidth=2, cmap='autumn')
plt.colorbar(strm.lines)

plt.show()

上記の実行結果は下記になります。

f:id:lib-arts:20190614164408p:plain
ベクトルの速度の絶対値が大きい点での色が黄色、小さい点が赤で表示されるように色付けが行われています。
このように、plt.streamplotを用いることでベクトル場を図示することができます。


1-2. plt.fillを用いた曲線や多角形の色付けの描画
1-2ではplt.fillを用いた曲線や多角形の色付けの描画を見ていきます。

Filled polygon — Matplotlib 3.1.0 documentation

上記のサンプルコードをまずは参考に見ていきます。koch_snowflakeを読み込んだのちに、コードを実行することで下記のような結果を得ることができます。

f:id:lib-arts:20190614165206p:plain
また、下記では色付けの変更も行っています。

f:id:lib-arts:20190614165225p:plain
plt.fillの入力の情報をまだ確認していないので、次に内容の確認を行っていきます。まずはxとyの行列のサイズを確認します。

f:id:lib-arts:20190614170207p:plain
上記を見たところ、fillの引数として与えているxとyはそれぞれx座標とy座標ということがわかります。確認のためにplt.plotやplt.scatterを用いて図示すると下記のようになります。

f:id:lib-arts:20190614170224p:plain

上記によってplt.fillの入力としては、xとyの座標を与えているということがわかりました。簡単な例で下記も試してみましょう。

x = np.array([1,-1,-1,1])
y = np.array([1,1,-1,-1])
plt.fill(x, y)
plt.show()

上記を実行すると下記のようになります。正方形の描画を行っています。

f:id:lib-arts:20190614170547p:plain
最後にドキュメントの内容も確認しておきます。

f:id:lib-arts:20190614170603p:plain

matplotlib.pyplot.fill — Matplotlib 3.1.0 documentation
上記では"Each polygon is defined by the lists of x and y positions of its nodes"とあり、多角形はノードのx座標、y座標のリストで定義されるとされており、xとyのノードの座標を与えるという認識で正しかったことがわかります。
このように、plt.fillを用いることで多角形の色付けを行うことができます。

 

1-3. plt.polarを用いた極座標の描画
1-3ではplt.polarを用いた極座標の描画を見ていきます。

f:id:lib-arts:20190614172009p:plain

matplotlib.pyplot.polar — Matplotlib 3.1.0 documentation
上記の仕様を見ると単に第一引数に角度(ラジアン)の情報、第二引数に長さの情報を与えるだけでさほど難しくなさそうなので、下記のコードを元に早速プロッティングを行っていきます。

import matplotlib.pyplot as plt

plt.polar(0,0,"yo")
plt.polar(0,1,"ro")
plt.polar(1,1,"bo")
plt.polar(2,1,"go")
plt.polar(0,2,"ro")
plt.polar(1,2,"bo")
plt.polar(2,2,"go")
plt.plot()

上記の実行結果としては下記のようになります。

f:id:lib-arts:20190614172027p:plain
角度がラジアン表記なので、円周率(3.14...)で180度を示すような座標系になっています。
このようにplt.polarを用いることで極座標表記を行うことができます。


2. まとめ
#3では発展的な描画の例として、plt.streamplot、plt.fill、plt.polarらについて取り扱いました。
#4ではタイトル付けや複数画像の表示など、描画にあたって知っておきたい内容についてまとめていきます。