如何在Matplotlib中绘制模糊点

9

正如问题所述,我正在寻找一种使用Matplotlib绘制模糊点的方法。我不想绘制一组点,然后应用过滤器来使整个图像变得模糊。相反,我想绘制一组点,每个点都有一个相关的模糊程度。

提前感谢您。


抱歉,使用内置的matplotlib函数无法实现。 - dwitvliet
1
@Banana - 实际上,这是与*Agg后端(除了OSX上的默认设置)有关,但它会相当慢。请看:http://matplotlib.org/examples/pylab_examples/demo_agg_filter.html - Joe Kington
1
实际上有几种不同的方法可以解决这个问题(虽然Banana正确指出你需要变得有点有创意)。一个关键考虑因素是你想让模糊大小保持数据坐标还是显示坐标不变。换句话说,当你放大时,模糊是否应该在显示中变得更大或者保持相同大小? - Joe Kington
嗨,@JoeKington。首先,感谢您的帮助。其次,不,我甚至还没有使用交互模式,只是保存图像以在Matplolib提供的界面之外显示它们。然后,模糊将保持固定状态。(; - pceccon
2个回答

10

这里有另一种解决方法。您可以使用 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()

模糊的标记图


非常好的解决方案!我之前不知道这个!非常感谢你! - pceccon

7
当你做不到的时候,就假装能做到。
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))

这样做会产生以下效果: enter image description here 这并不是完美的,但类似这样的东西可能已经满足了您的需求。需要考虑以下几点:
  • 字号现在是绝对单位,不会随着比例缩放(需要更多数学计算才能进行缩放)
  • 如果要每个点都有相等量的墨水,则必须减小较大斑点的 alpha 值
  • 你想让模糊直径反映数值(如此处)还是模糊区域?
  • 真正的“模糊”通常是高斯的,这不是;可以实现,但是大小和 alpha 缩放就变得有点麻烦了
  • 当模糊的点重叠时,您希望看到什么呢?
  • 在使用 alpha 值和颜色值进行数学计算时,请记住显示器的 gamma 函数。
因此,这只是一个丑陋的伪造品。有时它们看起来足够好,有时则不然。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接