Положение графика / разброса и размер маркера в одинаковых координатах - PullRequest
10 голосов
/ 15 февраля 2011

Я пытаюсь программно отобразить различные типы диаграмм в pylab.Функция разброса pylab отображает маркеры в разных координатах в координатах своей оси, но размеры маркеров выражаются в пикселях.Это имеет смысл для повседневных графиков.Однако я хочу дать координаты и размеры маркеров в тех же координатах!Например, следующий код отображает два кружка (0,0,0,0) и (0,5,0,5) размером 20 каждый.Они должны почти полностью перекрываться, так как радиус намного больше, чем расстояние между центрами.Однако это не так, потому что размеры указаны в пикселях, а позиции - в координатах оси.

import pylab
pylab.scatter([0,0.5], [0,0.5], s=20, c='b', marker='o')

Есть ли способ создать точечный график (или нарисовать любые фигуры, линии и т. Д.) с размерами и позициями, указанными в одинаковых координатах?Я заинтересован в выводе векторной графики (pdf, svg и т. Д.).

Ответы [ 2 ]

13 голосов
/ 16 февраля 2011

Функция pylab.scatter принимает размер значения, основанный на размере в точках ^ 2. Этот размер не будет зависеть от осей, так как это характер рассеянного графика (не имеет смысла, если вы сузите область рассеяния, чтобы точки стали больше).

Если вы хотите сказать, что нарисовать круги заданного размера, вы должны использовать команду окружности в pylab

import pylab
axes = pylab.axes()
circle1 = pylab.Circle((0,0), radius=20, alpha=.5)
circle2 = pylab.Circle((0.5,0.5), radius=20, alpha=.5)
axes.add_patch(circle1)
axes.add_patch(circle2)
pylab.axis('scaled')
pylab.show()

Если вам нужно что-то с разбросом, например, способностью, вы можете сделать что-то вроде

import pylab
import matplotlib

def my_circle_scatter(axes, x_array, y_array, radius=0.5, **kwargs):
    for x, y in zip(x_array, y_array):
        circle = pylab.Circle((x,y), radius=radius, **kwargs)
        axes.add_patch(circle)
    return True

def my_square_scatter(axes, x_array, y_array, size=0.5, **kwargs):
    size = float(size)
    for x, y in zip(x_array, y_array):
        square = pylab.Rectangle((x-size/2,y-size/2), size, size, **kwargs)
        axes.add_patch(square)
    return True

def my_polygon_scatter(axes, x_array, y_array, resolution=5, radius=0.5, **kwargs):
    ''' resolution is number of sides of polygon '''
    for x, y in zip(x_array, y_array):
        polygon = matplotlib.patches.CirclePolygon((x,y), radius=radius, resolution=resolution, **kwargs)
        axes.add_patch(polygon)
    return True

axes=pylab.axes()
my_circle_scatter(axes, [0,0.5], [0,0.5], radius=2, alpha=.5, color='b')
my_square_scatter(axes, [-3,-4,2,3], [1,-3,0,3], size=.5, alpha=.5, color='r')
my_polygon_scatter(axes, [-1,-2,3], [-3,0,3], radius=.5, resolution=3, alpha=.5, color='g')
my_polygon_scatter(axes, [4,1.5,3], [2,-1,-3], radius=.5, resolution=5, alpha=.5, color='k')
pylab.axis('scaled')
pylab.axis([-5,5,-5,5])
pylab.show()

См. http://matplotlib.sourceforge.net/api/artist_api.html#module-matplotlib.patches для других прорисовываемых объектов.

Пример вывода из первого фрагмента: matplotlib circles

Пример вывода из второго фрагмента: matplotlib scatter plot

РЕДАКТИРОВАТЬ для Гриффа: если вы хотите обрабатывать разные радиусы для каждой точки, вы можете сделать что-то прямое, например:

def my_circle_scatter_radii(axes, x_array, y_array, radii_array, **kwargs):
    for (x, y, r) in zip(x_array, y_array, radii_array):
        circle = pylab.Circle((x,y), radius=r, **kwargs)
        axes.add_patch(circle)
    return True

Логика одновременной обработки обоих случаев также проста (например, проверьте, является ли его radii_array типом int / float и, если это так, сделать его массивом).

2 голосов
/ 22 марта 2016

Коллекция патчей - лучший выбор, если вы действительно хотите сделать его похожим на plt.scatter.Предположим, что вы хотите построить разброс окружностей с заданным радиусом в единицах данных, вы можете взглянуть на этот пост , который предоставляет хорошо упакованную функцию с именем circles.

Если вы хотитечтобы использовать другие маркеры, такие как квадрат или многоугольник, вы можете переписать эту функцию соответствующими патчами, как сказано в ответе д-ра jimbob.

Вот пример

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

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

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

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

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...