Как построить размытые точки в Matplotlib

Как говорится в вопросе, я ищу способ построить размытые точки с помощью Matplotlib. Я не хочу строить набор точек, а затем применять фильтр для размытия всего изображения. Вместо этого я хотел бы построить набор точек, каждая из которых имеет соответствующий уровень размытия.

Заранее спасибо.


person pceccon    schedule 29.07.2014    source источник
comment
Извините, но это невозможно со встроенными функциями matplotlib.   -  person dwitvliet    schedule 29.07.2014
comment
@Banana - На самом деле, это с бэкэндами * Agg (по умолчанию для всего, кроме OSX), но это будет довольно медленно. Взгляните на: matplotlib.org/examples/pylab_examples/demo_agg_filter.html   -  person Joe Kington    schedule 29.07.2014
comment
На самом деле есть несколько разных способов сделать это (хотя Banana прав, что вам нужно немного проявить творческий подход). Ключевым моментом является то, хотите ли вы, чтобы размер размытия оставался фиксированным в координатах данных или координатах отображения. Другими словами, когда вы увеличиваете масштаб, должно ли размытие на дисплее увеличиваться или оно должно оставаться того же размера?   -  person Joe Kington    schedule 29.07.2014
comment
Привет, @JoeKington. Во-первых, спасибо за вашу помощь. Во-вторых, нет, я пока даже не использую интерактивный режим, а просто сохраняю изображения для отображения в другом интерфейсе, отличном от того, который предоставляется Matplolib. Тогда размытие останется фиксированным. (;   -  person pceccon    schedule 30.07.2014


Ответы (2)


Вот еще одна работа вокруг. Вы можете отображать изображение в каждом месте вместо маркера, используя BboxImage. Таким образом, вы можете размыть или манипулировать изображением любым удобным для вас способом. В этом руководстве содержится дополнительная информация об BboxImages.

import matplotlib.pyplot as plt
from scipy import ndimage
from matplotlib.image import BboxImage
from matplotlib.transforms import Bbox, TransformedBbox
import numpy as np

# Create and save an image with just a marker in it
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.plot(0.5,0.5,'*',ms=200)
ax1.set_ylim(0,1)
ax1.set_xlim(0,1)
plt.axis('off')
fig1.savefig('marker.png')

# Read in the same marker image
marker = plt.imread('marker.png')

# New figure and data
fig2 = plt.figure()
ax2 = fig2.add_subplot(111)
x = 8*np.random.rand(10) + 1
y = 8*np.random.rand(10) + 1
sigma = np.arange(10,60,5)

# Blur the marker and image plot the blurred image at each data point. 
for xi, yi, sigmai in zip(x,y,sigma):
    markerBlur = ndimage.gaussian_filter(marker,sigmai) # Blur the marker image

    # Create an BboxImage for the blurred marker and add it to the plot. 
    bb = Bbox.from_bounds(xi,yi,1,1)  
    bb2 = TransformedBbox(bb,ax2.transData)
    bbox_image = BboxImage(bb2,
                           norm = None,
                           origin=None,
                           clip_on=False)

    bbox_image.set_data(markerBlur)
    ax2.add_artist(bbox_image)

ax2.set_xlim(0,10)
ax2.set_ylim(0,10)
plt.show()

график с размытым маркером

person Molly    schedule 30.07.2014
comment
Довольно хорошее решение! Не знал об этом! Большое спасибо! - person pceccon; 01.08.2014

Когда вы не можете это сделать, подделайте это.

import matplotlib.pyplot as plt
import numpy as np

# some random data
x = np.random.random(100)
y = np.random.random(100)
z = np.random.random(100)

# z reflects the amount of defocus at each dot
# if z=0, the point is small (1 pt)
# if z=1, the point is large (50 pt)
# each dot is composed of different layers
fig = plt.figure()
ax = fig.add_subplot(111)
for i in np.arange(.1,1.01,.1):
    ax.scatter(x, y, s=(50*i*(z*.9+.1))**2, color=(0,0,0,.5/i/10))

Это дает:

введите здесь описание изображения

Это ни в коем случае не идеально, но что-то в этом роде может удовлетворить ваши потребности. Что следует учитывать:

  • размер точки теперь указан в абсолютных единицах, он не масштабируется (для масштабирования требуется больше математики)
  • если вы хотите иметь одинаковое количество чернил в каждой точке, вам придется уменьшить значение альфа-канала для больших пятен.
  • Вы хотите, чтобы диаметр размытия отражал значение (как здесь) или область размытия?
  • настоящее «размытие» обычно гауссово, это не так; это можно сделать, но тогда размер и масштабирование по альфа-каналу становятся немного длиннее
  • что вы хотите увидеть, когда размытые точки перекрывают друг друга?
  • при выполнении математических операций с альфа-значениями и значениями цвета помните о гамма-функции дисплея

Так что это просто уродливая подделка. Иногда они выглядят достаточно хорошо, иногда нет.

person DrV    schedule 29.07.2014