web-dev-qa-db-ja.com

Python散布図。マーカーのサイズとスタイル

散布図として表示するデータのセットがあります。各ポイントをサイズdxの正方形としてプロットします。

          x = [0.5,0.1,0.3]
          y = [0.2,0.7,0.8]
          z = [10.,15.,12.]
          dx = [0.05,0.2,0.1]

          scatter(x,y,c=z,s=dx,marker='s')

問題は、散布関数が読み取るサイズsがポイント数^ 2であることです。私が望むのは、各点が面積dx ^ 2の正方形で表されることです。この面積は「実」単位、プロット単位です。この点が得られることを願っています。

別の質問もあります。散布機能はマーカーを黒い境界線でプロットしますが、このオプションをドロップして境界線をまったく持たないようにするにはどうすればよいですか?

39
Brian

ユーザーデータ座標系から表示座標系に変換します。

また、edgecolors = 'none'を使用して、輪郭のない面をプロットします。

import numpy as np

fig = figure()
ax = fig.add_subplot(111)
dx_in_points = np.diff(ax.transData.transform(Zip([0]*len(dx), dx))) 
scatter(x,y,c=z,s=dx_in_points**2,marker='s', edgecolors='none')
42
remosu

Figureサイズに合わせてサイズを変更するマーカーが必要な場合は、パッチを使用できます。

from matplotlib import pyplot as plt
from matplotlib.patches import Rectangle

x = [0.5, 0.1, 0.3]
y = [0.2 ,0.7, 0.8]
z = [10, 15, 12]
dx = [0.05, 0.2, 0.1]

cmap = plt.cm.hot
fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal')

for x, y, c, h in Zip(x, y, z, dx):
    ax.add_artist(Rectangle(xy=(x, y),
                  color=cmap(c**2),        # I did c**2 to get Nice colors from your numbers
                  width=h, height=h))      # Gives a square of area h*h

plt.show()

enter image description here

ご了承ください:

  1. 正方形は(x,y)の中心にありません。 x、yは、実際には左下の正方形の座標です。このようにして、コードを簡素化します。 (x + dx/2, y + dx/2)を使用する必要があります。
  2. 色はホットカラーマップから取得されます。私はz ** 2を使用して色を与えました。また、これをあなたのニーズに適応させる必要があります

最後に、2番目の質問です。キーワード引数edgecolorまたはedgecolorsを使用して、散布図の境界線を取得できます。これらはそれぞれ、matplotlibカラー引数またはrgbaタプルのシーケンスです。パラメーターを「なし」に設定すると、境界線は描画されません。

21
joaquin

パッチのコレクションを使えばもっとうまくできると思います。文書によると:

この(PatchCollection)を使用すると、カラーマップをパッチの異種コレクションに簡単に割り当てることができます。

PatchCollectionは多数のパッチよりも高速に描画するため、これによりプロット速度も改善される場合があります。

データ単位で指定された半径の円の散布図をプロットするとします。

_def circles(x, y, s, c='b', vmin=None, vmax=None, **kwargs):
    """
    Make a scatter of circles plot of x vs y, where x and y are sequence 
    like objects of the same lengths. The size of circles are in data scale.

    Parameters
    ----------
    x,y : scalar or array_like, shape (n, )
        Input data
    s : scalar or array_like, shape (n, ) 
        Radius of circle in data unit.
    c : color or sequence of color, optional, default : 'b'
        `c` can be a single color format string, or a sequence of color
        specifications of length `N`, or a sequence of `N` numbers to be
        mapped to colors using the `cmap` and `norm` specified via kwargs.
        Note that `c` should not be a single numeric RGB or RGBA sequence 
        because that is indistinguishable from an array of values
        to be colormapped. (If you insist, use `color` instead.)  
        `c` can be a 2-D array in which the rows are RGB or RGBA, however. 
    vmin, vmax : scalar, optional, default: None
        `vmin` and `vmax` are used in conjunction with `norm` to normalize
        luminance data.  If either are `None`, the min and max of the
        color array is used.
    kwargs : `~matplotlib.collections.Collection` properties
        Eg. alpha, edgecolor(ec), facecolor(fc), linewidth(lw), linestyle(ls), 
        norm, cmap, transform, etc.

    Returns
    -------
    paths : `~matplotlib.collections.PathCollection`

    Examples
    --------
    a = np.arange(11)
    circles(a, a, a*0.2, c=a, alpha=0.5, edgecolor='none')
    plt.colorbar()

    License
    --------
    This code is under [The BSD 3-Clause License]
    (http://opensource.org/licenses/BSD-3-Clause)
    """
    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.patches import Circle
    from matplotlib.collections import PatchCollection

    if np.isscalar(c):
        kwargs.setdefault('color', c)
        c = None
    if 'fc' in kwargs: kwargs.setdefault('facecolor', kwargs.pop('fc'))
    if 'ec' in kwargs: kwargs.setdefault('edgecolor', kwargs.pop('ec'))
    if 'ls' in kwargs: kwargs.setdefault('linestyle', kwargs.pop('ls'))
    if 'lw' in kwargs: kwargs.setdefault('linewidth', kwargs.pop('lw'))

    patches = [Circle((x_, y_), s_) for x_, y_, s_ in np.broadcast(x, y, s)]
    collection = PatchCollection(patches, **kwargs)
    if c is not None:
        collection.set_array(np.asarray(c))
        collection.set_clim(vmin, vmax)

    ax = plt.gca()
    ax.add_collection(collection)
    ax.autoscale_view()
    if c is not None:
        plt.sci(collection)
    return collection
_

marker関数のすべての引数とキーワード(scatterを除く)は同様に機能します。 Gist を含むcircles楕円およびsquares/rectangles他の形状のコレクションが必要な場合は、自分で変更できます。

colorbarをプロットする場合は、colorbar()を実行するか、返されたコレクションオブジェクトをcolorbar関数に渡します。

例:

_from pylab import *
figure(figsize=(6,4))
ax = subplot(aspect='equal')

#plot a set of circle
a = arange(11)
out = circles(a, a, a*0.2, c=a, alpha=0.5, ec='none')
colorbar()

#plot one circle (the lower-right one)
circles(1, 0, 0.4, 'r', ls='--', lw=5, fc='none', transform=ax.transAxes)

xlim(0,10)
ylim(0,10)
_

出力:

Example Figure

18
Syrtis Major

これをPython 3互換にするために、次のコードスニペットを追加しました

try:
    basestring
except NameError:
    basestring = str

から

変数がpython 2と3の互換性)で文字列であるかどうかを確認する方法

basestringはPython 3.では利用できないため、これが必要です。Python 2では、basestringの目的はstrunicodeの両方を含めます。Python 3では、strunicodeの間に区別はありません。 str

0