爱心函数千千万,乘着这个“七夕”发几个matlplotlib做的爱心供大家参考。
最浪漫的爱心曲线当属笛卡尔送给葛莉丝汀的的a(1-sin(b)),这个函数最简单,但需要用到极坐标系,画起来有点像猴屁股
程序没有很详细的注释,如果不理解动画,可参照《使用matplotlib的动画模块快速更新曲线》的代码注释。想要了解更多的极坐标函数,可以看看官方的Polar Demo。
import numpy as np
from matplotlib.lines import Line2D
import matplotlib.pyplot as plt
import matplotlib.animation as animation
class LOVE:
def __init__(self,ax):
N = 50
self.ax=ax
#endpoint若为False,则圆周不完整
self.theta = np.linspace(0.0, 2 * np.pi, N, endpoint=True)
#a(1-sin(b)),a=1
radii = 1-np.sin(self.theta)
self.love = Line2D(self.theta, radii,color='r')
self.ax.add_line(self.love)
self.ax.set_rmax(3)
self.ax.set_rticks([])
#不显示极坐标系
#frame = plt.gca()
#frame.axes.get_yaxis().set_visible(False)
#frame.axes.get_xaxis().set_visible(False)
def update(self, a):
radii = a * (1 - np.sin(self.theta))
self.love.set_data(self.theta, radii)
return self.love,
#用正弦波控制小心心的缩放
def emitter():
angle=np.linspace(0.0, 2 * np.pi,50, endpoint=True)
x=0
while x<50:
a=np.sin(angle[x])*0.05+1
x=x+1
yield a
fig = plt.figure()
#生成的坐标系为极坐标系
ax = plt.subplot(projection='polar')
LOVE=LOVE(ax)
ani = animation.FuncAnimation(fig, LOVE.update, emitter, interval=10,
blit=True)
#制作gif
#ani.save('love_1.gif',writer='pillow',fps=10)
plt.show()
我在B站里发现了一个跟弹簧一样的爱心,于是抄了UP主的数学公式,也做了一个动画,这个动画看着稍微复杂一些,但因为用的是笛卡尔坐标系,所以代码写起来反而会更容易。
import numpy as np
from matplotlib.lines import Line2D
import matplotlib.pyplot as plt
import matplotlib.animation as animation
class Love:
def __init__(self, ax):
self.ax = ax
self.x = np.linspace(-2,2,100)
y=np.zeros(100)
self.line = Line2D(self.x, y,color='r')
self.ax.add_line(self.line)
self.ax.set_xlim(-2,2)
self.ax.set_ylim(-2,3)
def update(self, w):
y = np.sqrt(np.abs(self.x)) + 0.9 * np.sqrt(4 - np.square(self.x)) * np.sin(w * self.x)
self.line.set_data(self.x,y)
return self.line,
def emitter():
w = 0
while w < 86:
w = w + 1
yield w
#由于爱心在默认生成的窗口中不漂亮,所以在程序里写入size
fig, ax = plt.subplots(figsize=(5,6))
love = Love(ax)
ani = animation.FuncAnimation(fig, love.update, emitter, interval=10,
blit=True)
#制作gif
#ani.save('love_2.gif',writer='pillow',fps=10)
plt.show()