Skip to main content
 首页 » 编程设计

python之使用 matplotlib 的亚像素精度散点图

2025年05月04日21wayfarer

注:我是边写边想办法解决这个问题的。我的答案如下。

有没有一种简单的方法可以使用 matplotlib 获得圆的亚像素抗锯齿位置?我能够创建以下 .gif,但圆圈的运动按整数像素步进的事实确实困扰着我。

我当然可以渲染大图像 (plt.savefig("image.png",dpi=1000)) 并缩小,但增加的复杂性很痛苦(这是一个例子对于学生来说,因此导入额外的工具会惹恼学生,安装额外的工具会惹恼校园 IT!)

import matplotlib.pyplot as plt 
from math import sin,cos 
x=[] 
y=[] 
#Create 41**2 particles in the unit square 
for i in range(41): 
    for j in range(41): 
        x.append(i*0.05-1.0) 
        y.append(j*0.05-1.0) 
#5 second video at 30 fps = 150 frames 
for n in range(150): 
    plt.close('all') 
    fig, axes = plt.subplots(figsize=(5,5)) 
    #some cool motion 
    for i in range(len(x)): 
        x[i]+=0.001*cos(x[i]+3*y[i]) 
        y[i]+=0.001*sin(6*x[i]-4*y[i]) 
    #create the scatter plot 
    axes.scatter(x,y,s=3,antialiased=True) 
    axes.set_xlim(-1.4,1.4) 
    axes.set_ylim(-1.4,1.4) 
    axes.set_aspect('equal') 
    plt.savefig("out/fig%03d.png"%n,dpi=80) 

请您参考如下方法:

必须优化分散函数才能快速放置整数。如果您手动添加 Circle 对象,则会为您处理子像素抗锯齿。它慢了很多。示例:

import matplotlib.pyplot as plt 
from matplotlib.collections import PatchCollection 
from math import sin,cos 
x=[] 
y=[] 
#Create 41**2 particles in the unit square 
for i in range(41): 
    for j in range(41): 
        x.append(i*0.05-1.0) 
        y.append(j*0.05-1.0) 
#5 second video at 30 fps = 150 frames 
for n in range(150): 
    plt.close('all') 
    fig, axes = plt.subplots(figsize=(5,5)) 
    #adding the Circles to the plot using a PatchCollection is much faster. 
    patches=[] 
    #some cool motion 
    for i in range(len(x)): 
        x[i]+=0.001*cos(x[i]+3*y[i]) 
        y[i]+=0.001*sin(6*x[i]-4*y[i]) 
        patches.append(plt.Circle((x[i],y[i]),0.015)) 
    axes.add_collection(PatchCollection(patches, alpha=0.95)) 
    axes.set_xlim(-1.4,1.4) 
    axes.set_ylim(-1.4,1.4) 
    axes.set_aspect('equal') 
    plt.savefig("out/fig%03d.png"%n,dpi=80) 

结果: