pyplot散布図マーカーのサイズ


376

散布図のpyplotドキュメント:

matplotlib.pyplot.scatter(x, y, s=20, c='b', marker='o', cmap=None, norm=None,
                          vmin=None, vmax=None, alpha=None, linewidths=None,
                          faceted=True, verts=None, hold=None, **kwargs)

マーカーのサイズ

s:ポイント単位のサイズ^ 2。xとyと同じ長さのスカラーまたは配列です。

どのような単位points^2ですか?どういう意味ですか?ないs=100わけ10 pixel x 10 pixel

基本的に、異なるマーカーサイズで散布図を作成しようとしていますが、s数値の意味を理解したいと思います。


ポイントがフォントに使用される単位と同じであることを確認してください。
tacaswell 2013

@tcaswell、s=20つまり、マーカーのサイズがfontsize=20文字のサイズと等しいということですか?
LWZ 2013

いいえ、面積は20ポイント^ 2になります。fontsize=20文字の高さは20ポイントです(または、フォントの参照文字の高さが20ポイントです)。
tacaswell 2013

23
matplotlib.pyplot.plot()持っているmsパラメータ(markersize)と同等のmatplotlib.pyplot.scatter()パラメータをssize)。ただのリマインダー..
niekas

@neikas 1つはピクセル(マーカーサイズ)であり、もう1つはこの奇妙な2乗ポイント単位(サイズ)であるため、そうではないようです。これは常に私を混乱させてきましたが、視覚的に比例した方法で量を示すために使用される散布図マーカーのサイズと関係があると私は信じています。
heltonbiker

回答:


406

これは、サイズを定義する方法としてやや混乱を招く可能性がありますが、基本的にはマーカーの領域を指定します。つまり、マーカーの幅(または高さ)を2倍にするには、s4倍にする必要があります。[A = W H =>(2W)(2H)= 4Aであるため]

ただし、マーカーのサイズがこのように定義されているのには理由があります。面積は幅の2乗としてスケーリングされるため、幅を2倍にすると、実際にはサイズが2倍以上増加するように見えます(実際には4倍増加します)。これを確認するには、次の2つの例とそれらが生成する出力を検討してください。

# doubling the width of markers
x = [0,2,4,6,8,10]
y = [0]*len(x)
s = [20*4**n for n in range(len(x))]
plt.scatter(x,y,s=s)
plt.show()

与える

ここに画像の説明を入力してください

サイズが急激に増加することに注目してください。代わりに

# doubling the area of markers
x = [0,2,4,6,8,10]
y = [0]*len(x)
s = [20*2**n for n in range(len(x))]
plt.scatter(x,y,s=s)
plt.show()

与える

ここに画像の説明を入力してください

マーカーの見かけのサイズが直感的にほぼ直線的に増加します。

「ポイント」が何であるかについての正確な意味については、それはプロットの目的ではかなり恣意的であり、合理的に見えるまですべてのサイズを定数でスケーリングできます。

お役に立てれば!

編集:(@Emmaからのコメントに応じて)

それはおそらく私の側の混乱した表現です。質問は、円の幅を2倍にすることについて尋ねたので、各円の最初の図では(左から右に移動して)幅が前の2倍になっているので、領域では、底が4の指数です。同様に、2番目の例各円の面積は、最後の円の2倍で、底が2の指数です。

しかし、2倍の領域が円を目に2倍の大きさにするように見えるのは、2番目の例(ここでは領域をスケーリングしています)です。したがって、円を次の係数で表示したい場合nより大きなn、半径ではなく係数で面積を増やし、見かけのサイズが面積に比例して拡大縮小するようにします。

編集するして、@ TomaszGandorによるコメントを視覚化します。

これは、マーカーサイズのさまざまな関数で次のようになります。

指数、正方形、または線形サイズ

x = [0,2,4,6,8,10,12,14,16,18]
s_exp = [20*2**n for n in range(len(x))]
s_square = [20*n**2 for n in range(len(x))]
s_linear = [20*n for n in range(len(x))]
plt.scatter(x,[1]*len(x),s=s_exp, label='$s=2^n$', lw=1)
plt.scatter(x,[0]*len(x),s=s_square, label='$s=n^2$')
plt.scatter(x,[-1]*len(x),s=s_linear, label='$s=n$')
plt.ylim(-1.5,1.5)
plt.legend(loc='center left', bbox_to_anchor=(1.1, 0.5), labelspacing=3)
plt.show()

2
私はおそらくあなたのポイントを誤解しているかもしれませんが、2番目の例では、sを指数関数的に増加させ(s = [20、40、80、160、320、640])、これにより線形に見えるサイズの増加が見られます。サイズを線形的に増加させると(例:s = [20、40、60、80、100、120])、線形に見える結果が得られれば、より意味がありませんか?
Emma

@Emmaあなたの直感は正しいです、それは私の側の言い回しが悪いです(またはx軸スケーリングの選択が悪い)。コメントには長すぎたので、編集でさらに説明しました。
ダン

1
sフィギュアウィンドウの大きさに応じて値を変えることは可能ですか?つまり、図ウィンドウを最大化する場合は、より大きなサイズのマークを付けたいです。
シグル

2
素晴らしい例(必要なものだけ!)これは4 ** nand 2 ** nである必要はありませんが、n ** 4and n ** 2です。2 ** n2番目のプロット円の直径の面で直線的に拡張できません。それでもまだ速すぎます(それだけではありません)。
Tomasz Gandor

1
短く言えば、2番目のプロットは指数の平方根を示しています-これはもう1つの指数であり、少し急勾配ではありません。
Tomasz Gandor

218

ここでの他の回答sはマーカーの領域を示すと主張しているため、これは必ずしもそうではないことを明確にするために、この回答を追加します。

ポイント単位のサイズ^ 2

の引数sはをplt.scatter示しますmarkersize**2。ドキュメントが言うように

s:スカラーまたはarray_like、形状(n、)、オプションの
サイズ(ポイント単位)^ 2。デフォルトはrcParams ['lines.markersize'] ** 2です。

これは文字通り取ることができます。xポイントの大きいマーカーを取得するには、その数を2乗してs引数に渡す必要があります。

したがって、ラインプロットのマーカーサイズと散布サイズの引数の関係は正方形です。サイズが10ポイントのプロットマーカーと同じサイズの散布マーカーを作成するには、を呼び出す必要がありますscatter( .., s=100)

ここに画像の説明を入力してください

import matplotlib.pyplot as plt

fig,ax = plt.subplots()

ax.plot([0],[0], marker="o",  markersize=10)
ax.plot([0.07,0.93],[0,0],    linewidth=10)
ax.scatter([1],[0],           s=100)

ax.plot([0],[1], marker="o",  markersize=22)
ax.plot([0.14,0.86],[1,1],    linewidth=22)
ax.scatter([1],[1],           s=22**2)

plt.show()

「エリア」へのつながり

それでは、なぜ他の回答やドキュメントでさえ、sパラメータに関して「面積」について語っているのでしょうか。

もちろん、ポイントの単位** 2は面積の単位です。

  • 正方形のマーカーの特殊なケースでmarker="s"は、マーカーの面積は実際にはsパラメーターのます。
  • 円の場合、円の面積はarea = pi/4*sです。
  • 他のマーカーについては、マーカーの領域との明らかな関係さえないかもしれません。

ここに画像の説明を入力してください

ただし、すべての場合において、マーカーの面積はsパラメーターに比例します。これは、ほとんどの場合実際にはそうではありませんが、それを「エリア」と呼ぶ動機です。

マーカーの長さや直径ではなく、異なるパッチを比較するときに知覚されるのはマーカーの領域であるため、マーカーの領域に比例する量で散布マーカーのサイズを指定することは、これまでのところ意味があります。つまり、基になる量を2倍にすると、マーカーの面積が2倍になります。

ここに画像の説明を入力してください

ポイントとは?

これまでのところ、スキャッターマーカーのサイズが何を意味するかに対する答えは、ポイント単位で与えられます。ポイントは、フォントがポイントで指定されるタイポグラフィでよく使用されます。また、線幅はしばしばポイントで指定されます。matplotlibのポイントの標準サイズは1インチあたり72ポイント(ppi)です。したがって、1ポイントは1/72インチです。

ポイントではなくピクセルでサイズを指定できると便利な場合があります。図形のdpiも72の場合、1ポイントは1ピクセルです。Figureのdpiが異なる場合(matplotlibのデフォルトはfig.dpi=100)、

1 point == fig.dpi/72. pixels

したがって、散布マーカーのポイント単位のサイズは、図のdpiごとに異なって見えますが、10 x 10ピクセル^ 2のマーカーを作成することができ、常に同じ数のピクセルがカバーされます。

ここに画像の説明を入力してください ここに画像の説明を入力してください ここに画像の説明を入力してください

import matplotlib.pyplot as plt

for dpi in [72,100,144]:

    fig,ax = plt.subplots(figsize=(1.5,2), dpi=dpi)
    ax.set_title("fig.dpi={}".format(dpi))

    ax.set_ylim(-3,3)
    ax.set_xlim(-2,2)

    ax.scatter([0],[1], s=10**2, 
               marker="s", linewidth=0, label="100 points^2")
    ax.scatter([1],[1], s=(10*72./fig.dpi)**2, 
               marker="s", linewidth=0, label="100 pixels^2")

    ax.legend(loc=8,framealpha=1, fontsize=8)

    fig.savefig("fig{}.png".format(dpi), bbox_inches="tight")

plt.show() 

データ単位の散布に関心がある場合は、この回答を確認してください。


プロットの実際の座標で、たとえば0.1の直径をカバーする円を取得するために散布に与えるsパラメーターをどのように計算するのか(たとえば、(0 、0)から(1,1)へ?
アナトリーアレクセーエフ

@AnatolyAlekseevそれはこの質問で答えられるべきです。
ImportanceOfBeingErnest

21

マーカーサイズを使用して、プロットメソッドで円のサイズを指定できます

import numpy as np
import matplotlib.pyplot as plt

x1 = np.random.randn(20)
x2 = np.random.randn(20)
plt.figure(1)
# you can specify the marker size two ways directly:
plt.plot(x1, 'bo', markersize=20)  # blue circle with size 10 
plt.plot(x2, 'ro', ms=10,)  # ms is just an alias for markersize
plt.show()

ここから

ここに画像の説明を入力してください


問題はscatterplotに関するものであり、matplotlibでは2つのプロット関数に異なるパラメーター(plotにmarkerizescatterにはs)があります。したがって、この答えは当てはまりません。
ドム

3
@Dom賛成票を投じました。「pyplotプロットマーカーサイズ」を検索しても、この質問がGoogleの最初の結果としてポップアップ表示されるため、この回答が役立ちます。
Przemek D 2017

plotメソッドとscatterメソッドはpltで異なることを知っていますが、どちらも「scatter plot」を実現し、マーカーサイズを調整できるため、プロットメソッド@Domを使用する場合、この答えは別の回避策です
zhaoqing

18

マーカーの領域です。つまり、s1 = 1000との場合s2 = 4000、各円の半径の関係はですr_s2 = 2 * r_s1。次のプロットを参照してください。

plt.scatter(2, 1, s=4000, c='r')
plt.scatter(2, 1, s=1000 ,c='b')
plt.scatter(2, 1, s=10, c='g')

ここに画像の説明を入力してください

投稿を見たときも同じ疑問があったので、この例を実行してから、画面上で定規を使用して半径を測定しました。


これは最もクリーンで脂肪のない答えです。ありがとう
Ayan Mitra

6

この目的で、最初に「スキャッター」を使用することも試みました。かなりの時間を無駄にした後、私は次の解決策に落ち着きました。

import matplotlib.pyplot as plt
input_list = [{'x':100,'y':200,'radius':50, 'color':(0.1,0.2,0.3)}]    
output_list = []   
for point in input_list:
    output_list.append(plt.Circle((point['x'], point['y']), point['radius'], color=point['color'], fill=False))
ax = plt.gca(aspect='equal')
ax.cla()
ax.set_xlim((0, 1000))
ax.set_ylim((0, 1000))
for circle in output_list:    
   ax.add_artist(circle)

ここに画像の説明を入力してください

これはこの質問への回答に基づいています


とても役に立ちました。しかし、なぜ2つのループを使用するのでしょうか。
grabantot

1
@grabantotには理由がなく、あまり考えすぎませんでした。
Ike

2

円のサイズがのパラメータの2乗に対応している場合はs=parameter、次のように、サイズ配列に追加する各要素に平方根を割り当てます。s=[1, 1.414, 1.73, 2.0, 2.24]これらの値を受け取ってそれらを返すと、それらの相対的なサイズが増加します。二乗プログレッションの平方根。線形プログレッションを返します。

プロットへの出力を取得するときに、それぞれを2乗するとしますoutput=[1, 2, 3, 4, 5]。リストの解釈を試してください:s=[numpy.sqrt(i) for i in s]


1
すべきでi in outputはないのですか?
シグル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.