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, где эта область находится в "реальных" единицах, единицах графика. Надеюсь, вы сможете получить этот момент.
У меня также есть другой вопрос. Функция рассеяния отображает маркеры с черной рамкой, как я могу отказаться от этой опции и вообще не иметь границы?
Ответы
Ответ 1
Перевести из системы координат пользовательские данные в систему координат отображения.
и используйте 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')
Ответ 2
Если вы хотите, чтобы маркеры изменялись с размером фигуры, вы можете использовать патчи:
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]()
Обратите внимание, что:
- Квадраты не центрированы на
(x,y)
. x, y на самом деле являются коордами
квадрат внизу слева. Я разрешил это сделать, чтобы упростить мой код. Вы
следует использовать (x + dx/2, y + dx/2)
.
- Цвет получается из горячей цветовой карты. Я использовал z ** 2 для получения цветов.
вы также должны адаптировать это к вашим потребностям.
Наконец, для вашего второго вопроса. Вы можете получить границу меток разброса с помощью аргументов ключевого слова edgecolor
или edgecolors
. Это аргумент цвета matplotlib или последовательность кортежей rgba, соответственно. Если вы установите параметр "Нет", границы не будут рисоваться.
Ответ 3
Я думаю, что мы можем сделать это лучше с коллекцией патчей.
Согласно документам:
Это (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, включая круги, эллипсы и квадратов/.. Если вам нужна коллекция другой формы, вы можете ее самостоятельно изменить.
Если вы хотите построить цветную панель, просто запустите 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)
Вывод:
![Пример Рисунок]()
Ответ 4
Чтобы сделать этот Python 3 совместимым, я добавил следующий фрагмент кода
try:
basestring
except NameError:
basestring = str
от
Как проверить, является ли переменная строкой с совместимостью python 2 и 3
Это необходимо, потому что basestring
недоступен в Python 3. В Python 2 целью basestring
было включение как str
, так и unicode
. В Python 3 нет различий между str
и unicode
, а просто str
.