オタク日記
(Mac と Linux, 2017Q4)
目次
2017-12-28 (Thu): Matplotlib, お前もかっ! (その 2)
古い日記:
2017Q3
2017Q2
2017Q1
2016Q4
2016Q3
2016Q2
2016Q1
2015Q4
2015Q3
2015Q2
2015Q1
2014Q4
2014Q3
2014Q2
2014Q1
2013Q4
2013Q3
2013Q2
2013Q1
2012 年
2011 年
2010 年
2009 年
2008 年
2007 年
2006 年
2005 年
2004 年
2003 年
2002 年
2001 年
2017-12-28 (Thu): Matplotlib, お前もかっ! (その 2)
Matplotlib-2 (mpl-2) で「あるべきプロット」を目指す
「Matplotlib, お前もかっ!」の記事を書いてから、もう 1 年にもなるのか……。 その時は「しばらくは、1.5.3 で凌ごう」なんて殊勝な決意をしていたようだが、 私がこのような件で一年も放置(我慢)できる筈がない。 つい、色々ごちゃごちゃと「時間の無駄」をやってました。
さて、その時の「かくあるべし」を再掲すると、
- プロットする範囲は実線で囲む。
- tick はその実線の枠の内側に、tick value (目盛値) は tick に対応する箇所に書く。
- X/Y 軸の両端にも tick value をつける。
- Y 軸のラベルは、横書を 90 度回転したもの。
- 理論値、計算値は太い実線で、
- データポイントは、(中抜きの)○ で、
- データポイントに線を追加する場合は、 (データポイントを結ぶ「折れ線」ではなく)「スムージングした曲線」を示す。
- 複数のデータをプロットする場合は、色分けではなく、 マーカーの形や、line style を変える事で識別する。
この内、8. は既に無意味な制限になっているようなので、無視するとしても、 そこで例示したグラフは、上の 6. に違反している。(つまり、「中抜き」の circle になっていない。)Matplotlib-1.x (以下、mpl-1) ではすぐにはやり方が思い出せなかった……
Matplotlib-2.x (以下 mpl-2) でこれを実現するのは然程難しくはなく、些 かの cut & try で次にようなプロットを得た。
Mpl-2 でのディフォルトにする
ただこれをディフォルトにする、 すなわち最少のパラメータ変更でこのようなプロットを得られるようにする、 のは少々面倒だった。
Mpl-2 のインストールは様々な方法で可能であるが、ここではPyVenv
(% python36 -m venv pve36
で作った環境) だと仮定する。
この場合、pip で matplotlib をインストールすると、
(pve36) fukuda@hawk:~/pve36% find . -name matplotlibrc ./lib/python3.6/site-packages/matplotlib/mpl-data/matplotlibrcのように
matplotlibrc
が置かれるので、
これを、home directory (~/pve36/) にコピー・編集して
(pve36) fukuda@hawk:~/pve36% diff matplotlibrc.orig matplotlibrc
#1)
336,340c336,338
< #axes.autolimit_mode : data # How to scale axes limits to the data.
ber
< #axes.xmargin : .05 # x margin. See `axes.Axes.margins`
< #axes.ymargin : .05 # y margin See `axes.Axes.margins`
---
> axes.autolimit_mode : round_numbers
> axes.xmargin : 0.0 # x margin. See `axes.Axes.margins`
> axes.ymargin : 0.0 # y margin See `axes.Axes.margins`
#2)
364c362
< #xtick.top : False # draw ticks on the top side
---
> xtick.top : True # draw ticks on the top side
374c372
< #xtick.direction : out # direction: in, out, or inout
---
> xtick.direction : in # direction: in, out, or inout
382c380
< #ytick.right : False # draw ticks on the right side
---
> ytick.right : True # draw ticks on the right side
391c389
< #ytick.direction : out # direction: in, out, or inout
---
> ytick.direction : in # direction: in, out, or inout
<
ここに、
- #1) axes.autolimit_mode と axes.{x|y}margin の変更によって、tick とそれに対応する label が表示範囲の端につくようになる。
- #2) これらの変更によって、表示範囲の四周に「内向き」の tick がつくようになる。
こうしておくと、次のような Python command で、上記のプロットが得られる。
(pve36) fukuda@hawk:~/pve36% ipython Python 3.6.4 (default, Dec 21 2017, 20:32:44) Type 'copyright', 'credits' or 'license' for more information IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help. In [1]: import numpy as np In [2]: import matplotlib.pyplot as plt In [3]: x = np.arange(-10, 10, 0.01) In [4]: y = np.cos(x)*np.exp(-x*x/10) + 0.5 In [5]: x1 = np.arange(-10, 10, 0.7) In [6]: y1 = np.random.normal(np.cos(x1)*np.exp(-x1*x1/10) + 0.5, 0.02) In [7]: plt.plot(x, y, x1, y1, 'o', mfc="white") Out[7]: [<matplotlib.lines.Line2D at 0x1090513c8>, <matplotlib.lines.Line2D at 0x109051518>] In [8]: plt.xlabel("Radial Position (m)") Out[8]: Text(0.5,0,'Radial Position (m)') In [9]: plt.ylabel("Magnetic Field (A/m)") Out[9]: Text(0,0.5,'Magnetic Field (A/m)') In [10]: plt.show()
上記 [1]〜[6] は「データの作成」だし、[8], [9]
は言わばつけ足しで、
データを確認する段階では普通はこんな事はやらないので、
ここでの肝は、[7] の記述。これをできるだけ簡略化したい、というのが目標で、
理想は
plt.plot(x, y, x1, y1, 'o')
だけで済ます事だが、残念ながら、
mfc="white"
を省略するために必要な matplotlib
の対応パラメータ (例えば markers.fillcolor
?)
を見つけられなかった。
少々不本意ではあるが、mfc="white"
を省略しても、まあ我慢できるプロットができるので、
このあたりで手を打つ事にする。
10/1,792,065 Taka Fukuda Last modified: 2018-02-14 (Wed) 14:50:49 JST