Сюжет питона разброса. Размер и стиль маркера

у меня есть набор данных, которые я хочу показать в виде диаграммы рассеяния. Я хочу, чтобы каждая точка была построена как квадрат размера 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, где эта область находится в "реальных" единицах, единицах графика. Надеюсь,вы поймете.

у меня также есть еще один вопрос. Функция разброса маркеры с черная граница, как я могу отказаться от этой опции и вообще не иметь границы?

4 ответов


перевести данные пользователя системы координат дисплей система координат.

и используйте 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')

если вы хотите маркеры, которые изменяют размер с размером фигуры, вы можете использовать патчи:

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, чтобы дать цвета. вы должны также приспособить это к вашему должен

наконец, для вашего второго вопроса. Вы можете получить границу знаков разброса, используя ключевое слово arguments edgecolor или edgecolors. Это цветовой аргумент matplotlib или последовательность кортежей rgba соответственно. Если для параметра задано значение "None", границы не рисуются.


Я думаю, что мы можем сделать это лучше с набором патчей. По документам:

это (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) of scatter функция будет работать аналогичным образом. Я написал суть в том числе кружки, эллипсы и площади/прямоугольников. Если вам нужна коллекция другой формы, вы можете изменить ее самостоятельно.

если вы хотите построить colorbar просто запустить colorbar() или передать возвращенную коллекцию возражаю


чтобы сделать этот Python 3 совместимым, я добавил следующий фрагмент кода

try:
    basestring
except NameError:
    basestring = str

С

Как проверить, является ли переменная строкой с совместимостью python 2 и 3

это необходимо, потому что basestring недоступно в Python 3. В Python 2, цель basestring включить как str и unicode. В Python 3 нет различия между str и unicode и просто str.