結論
s
パラメーターがマーカーサイズを設定するパラメーターです。
plt.scatter(x, y, marker=".", s=1, linewidths=0)
※s
パラメーターを見逃していて色々いじくり回していました。コメントでやりかたを教えていただいたのでこの記事の内容はこれで終わりです。
遺物
お恥ずかしいですが試行錯誤の履歴は残しておきます。よっぽど変なマーカーをプロットしたい時に役に立つかもしれません。
クリックして展開
要約
タイトル通り。やろうとしたらなかなか方法が見つからなかったので。
結論だけ読みたい人は 結論Axesを用いた方法 へ
調べてたらちゃんとした方法が見つかったので更新しました 2020/03/19/21:29
前フリ
Pythonのグラフ描画ライブラリmatplotlibで散布図を描くとき、すごく細かい点をブワーッと並べたいときがありますよね。
plt.scatter
のマーカーはmarker
パラメーターで指定でき、細かい点を打つときはmarker='.'
とします。 ( ※matplotlib.pyplot.scatter )
しかしこの'.'
のマーカー(ドキュメントのdescriptionでは「point」と呼ばれています)、これでもまだちょっと大きい気がします。
rand = lambda n:[np.random.rand() for _ in range(n)]
xy = (rand(100), rand(100))
plt.scatter(*xy, marker=".")
マーカーの枠線を消してみましょう。
plt.scatter(*xy, marker=".", linewidth=0)
若干小さくなった気がしますがこれでもまだ大きい気がします。もっとゴミみたいな点が打ちたい。
matplotlib.markers の説明を読んでみると「","::pixel」というのがあります。そうそう、ピクセル単位レベルの点が打ちたかったのです。
plt.scatter(*xy, marker=",")
どうしてこうなった……
どうやらサイズが規格化されているらしく、形を指定するとこのサイズいっぱいになるように拡大縮小されるようです。
結論 めんどくさい例
マーカーサイズの規格化を無効にするパラメーターが見つからなかったので姑息的に「規格化されても小さく見えるマーカー」を作ってみます。(直接マーカーサイズを指定できる方法をご存知のかたは教えて下さいm(_ _)m)(Axesを使った例へ)
marker
パラメーターに「2次元座標のタプルの配列」を与えることで任意の多角形を描かせることができます。
これを利用して幅ゼロの対角線を引いてサイズを確保してから中心に小さく四角を作ります。
t = 0.1
plt.scatter(*xy, marker=[(0,0), (-1,-1), (1,1), (0,0), (t,t), (-t,t), (-t,-t), (t,-t), (t,t), (0,0)], linewidths=0)
ゴミみたいな点を打つことに成功しました!
マーカーオブジェクトを作って0~1倍の任意のサイズの点を打てるようにしてみました。
from matplotlib.markers import MarkerStyle
dot = lambda t: MarkerStyle([(0,0), (-1,-1), (1,1), (0,0), (t,t), (-t,t), (-t,-t), (t,-t), (t,t), (0,0)])
plt.scatter(*xy, marker=dot(0.2), linewidths=0)
正直もっとまともな方法あるやろ……と思われるので、まっとうな方法で小さい点を打つ方法をご存じの方はぜひご一報ください。よろしくお願いします。
Axesを用いた方法
Axes.plot
ではLine2Dのパラメーターを指定でき、ここにmarkersize
が存在することに気づきました。
fig, ax = plt.subplots()
ax.plot(*xy, linestyle='none', marker=',', markersize=1)
これが一番まともな方法だと思います。
ちょっとややこしいことをしようとするならやはりオブジェクト指向インターフェースを使うべきですね。
こちらの記事が参考になります。早く知っておきたかったmatplotlibの基礎知識、あるいは見た目の調整が捗るArtistの話 @skotaro さん
※小さい点でやりたかったこと
こうやって濃淡を点の密度で表現してみたかったのです。
func = lambda x,y:np.sin(x*np.pi)**2 * np.exp(-y**2/2)
n = 100
dx = 0.02
xlin = np.arange(-2,2,dx)
ylin = np.arange(-2,2,dx)
xx, yy = np.meshgrid(xlin, ylin)
pltx, plty = [], []
for x, y in zip(xx.flatten(), yy.flatten()):
dense = func(x+dx/2, y+dx/2)
pltx += [x+np.random.rand()*dx for _ in range(int(dense*n))]
plty += [y+np.random.rand()*dx for _ in range(int(dense*n))]
plt.scatter(pltx, plty, s=0.01, marker='.', alpha=0.1)
plt.xlim(-2,2)
plt.ylim(-2,2)
plt.show()