一旦 SymPy Plotting Backends で p = plot()
などとしてプロットしたら,あとは ax = p.ax
として ax
に対して通常どおりの Matplotlib のオプション設定をしていけばよいという話。
SymPy は関数を symbolic expression のままでグラフにできるので,NumPy にたよらないという方針でやってみる。
SymPy Plotting Backends (SPB) での描画例
# 念のため,あらためて必要なものを import
from sympy import *
# 1文字変数の Symbol の定義が省略できる
from sympy.abc import *
# π
from sympy import pi
Pi = float(pi)
# SymPy Plotting Backends (SPB)
from spb import *
# ticks の設定用
import matplotlib.ticker as tck
# NumPy は import しない
# import numpy as np
# グラフを SVG で Notebook にインライン表示
%config InlineBackend.figure_formats = ['svg']
SymPy Plotting Backends (SPB) を import すると,外枠とグリッドが自動で描かれる。
plot(sin(x), (x, -pi, pi), ylabel="sin x");
xticks, yticks のカスタマイズ
$x$ 軸,$y$ 軸の目盛の刻み幅とラベルの設定例(NumPy にたよらずに)。np.linspace()
や np.arange()
を使わずに xticks, yticks を設定するのに,Python の標準的なリスト作成機能を使う。たとえば…
[0.5*i for i in range(-2, 3)]
# いったん SymPy でプロットする(非表示)
p = plot(sin(x), (x, -pi, pi), ylabel="sin x", show=False)
ax = p.ax
# x 軸の目盛は 0.5π ごとに
ax.set_xticks([0.5*i*Pi for i in range(-2, 3)])
ax.set_xticklabels([('%g' % (0.5*i))+" $\pi$" for i in range(-2,3)])
# y の目盛を 0.5 ごとに
ax.set_yticks([0.5*i for i in range(-2, 3)]);
$1\, \pi$ とか $0\,\pi$ とか,今ひとつなので少し面倒だが一つずつ設定してみる。
p = plot(sin(x), (x, -pi, pi), ylabel="sin x", show=False)
ax = p.ax
# x 軸の目盛は 0.5π ごとに
ax.set_xticks([0.5*i*Pi for i in range(-2, 3)])
# x 軸の目盛のラベルを手動で設定
ax.set_xticklabels(["$-\pi$", "$-\pi/2$", "$0$", "$\pi/2$", "$\pi$"])
# y の目盛を 0.5 ごとに
ax.set_yticks([0.5*i for i in range(-2, 3)]);
grid の linestyle のカスタマイズ
グリッドを薄い灰色の細めの点線にして目立たなくさせる。
p = plot(sin(x), (x, -pi, pi), ylabel="sin x", show=False)
ax = p.ax
ax.set_xticks([0.5*i*Pi for i in range(-2, 3)])
ax.set_xticklabels(["$-\pi$", "$-\pi/2$", "$0$", "$\pi/2$", "$\pi$"])
ax.set_yticks([0.5*i for i in range(-2, 3)]);
# grid を細い点線で
ax.grid(True, which="major", color="lightgray", dashes=(3, 5), linewidth=0.5);
副目盛 minorticks の表示とカスタマイズ
主目盛は $0.5\,\pi$ ごとなので,その間に副目盛 (minorticks) もつける。
また,副目盛にもグリッドをつけると煩わしいので,グリッドは主目盛のみに。
p = plot(sin(x), (x, -pi, pi), ylabel="sin x", show=False)
ax = p.ax
ax.set_xticks([0.5*i*Pi for i in range(-2, 3)])
ax.set_xticklabels(["$-\pi$", "$-\pi/2$", "$0$", "$\pi/2$", "$\pi$"])
ax.set_yticks([0.5*i for i in range(-2, 3)]);
ax.grid(True, which="major", color="lightgray", dashes=(3, 5), linewidth=0.5)
# 副目盛も表示
ax.minorticks_on()
# 副目盛には grid をつけない
ax.grid(False, which="minor")
# 副目盛の刻み幅は自動でつくが,以下のようにカスタマイズ可
# x の副目盛は 0.1π ごとに
ax.set_xticks([0.1*i*Pi for i in range(-10, 11)], minor=True)
# y の副目盛は 0.1 ごとに
ax.set_yticks([0.1*i for i in range(-10, 11)], minor=True);
x 軸, y 軸の表示
$x$ 軸($y = 0$)と $y$ 軸($x = 0$)を axhline()
と axvline()
を使って表示させる。通常のグリッドと区別するために黒色で。
p = plot(sin(x), (x, -pi, pi), ylabel="sin x", show=False)
ax = p.ax
ax.set_xticks([0.5*i*Pi for i in range(-2, 3)])
ax.set_xticklabels(["$-\pi$", "$-\pi/2$", "$0$", "$\pi/2$", "$\pi$"])
ax.set_yticks([0.5*i for i in range(-2, 3)]);
ax.grid(True, which="major", color="lightgray", dashes=(3, 5), linewidth=0.5)
ax.minorticks_on()
ax.grid(False, which="minor")
ax.set_xticks([0.1*i*Pi for i in range(-10, 11)], minor=True)
ax.set_yticks([0.1*i for i in range(-10, 11)], minor=True)
# x軸 y軸
ax.axhline(0, color='black', dashes=(3, 5), linewidth=0.5)
ax.axvline(0, color='black', dashes=(3, 5), linewidth=0.5);
p.save("spbax05.svg");
参考:Locater, Formatter を使った ticks のカスタマイズ
以下のように matplotlib.ticker
を import し,MultipleLocator()
や FormatStrFormatter()
を使って目盛・ラベルの設定ができる。
ただし,$x = 3.1415…$ のところに $\pi$ とラベルをつけるためには少し工夫がいる。以下では $x = 1$ のところに $\pi$ とラベルをつけている。$y = \sin \pi x$ としているので,実効的には $x = 1$ のときは $ y = \sin \pi$ の値になっているのだが…
import matplotlib.ticker as tck
# sin の引数に π をかけ,x の範囲を -1 から 1 に
p = plot(sin(pi*x), (x, -1, 1), ylabel="sin x", show=False)
ax = p.ax
ax.grid(True, which="major", color="lightgray", dashes=(3, 5), linewidth=0.5)
ax.axhline(0, color='black', dashes=(3, 5), linewidth=0.5)
ax.axvline(0, color='black', dashes=(3, 5), linewidth=0.5);
# x の主目盛を 0.5π ごとに
ax.xaxis.set_major_locator(tck.MultipleLocator(0.5))
ax.xaxis.set_major_formatter(tck.FormatStrFormatter('%g $\pi$'))
# y の主目盛を 0.5 ごとに
ax.yaxis.set_major_locator(tck.MultipleLocator(0.5));
# 副目盛も表示
ax.minorticks_on()
# x 軸の副目盛は 0.1 ごとに
ax.xaxis.set_minor_locator(tck.MultipleLocator(0.1))
# y 軸の副目盛は 0.1 ごとに
ax.yaxis.set_minor_locator(tck.MultipleLocator(0.1))
# 副目盛には grid をつけない
ax.grid(False, which="minor");