Ich bin süchtig nach der folgenden Sin-Cos-t 3D-Animation, die vor 3 Tagen auf Twitter erschien, also werde ich sie zusammenfassen. Ich wollte eine interessantere Lisaju-Figur mit einem leichten Kleber zeichnen, der eine gewöhnliche Lisaju-Figur zu sein scheint. .. .. Ich war süchtig danach. https://twitter.com/i/status/1302164499139502080 Ich wollte das gleiche Bild zeichnen, gab aber an folgenden Stellen auf.
・ Axes3D-Animation ・ Sin-Cos-t-Animation
Zuerst dachte ich, obwohl es 3D war, dass es möglich sein würde, mit so etwas wie einer Referenz zu arbeiten. 【Referenz】 [Matplotlib basic] Versuchen Sie, ein dynamisches Diagramm zu schreiben ♬ ~ Videoausgabe; Gif-Animation Tatsächlich finden Sie in sin-cos-t Code ähnlich wie Gugu: 【Referenz】 ② [Matplotlib] Visualisierung von 3D-Daten
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
#Figur hinzufügen
fig = plt.figure(figsize = (8, 8))
#3D-Achsen hinzugefügt
ax = fig.add_subplot(111, projection='3d')
#Legen Sie den Titel der Achsen fest
ax.set_title("Helix", size = 20)
#Achsenbeschriftung einstellen
ax.set_xlabel("x", size = 14)
ax.set_ylabel("y", size = 14)
ax.set_zlabel("z", size = 14)
#Achsenskala einstellen
ax.set_xticks([-1.0, -0.5, 0.0, 0.5, 1.0])
ax.set_yticks([-1.0, -0.5, 0.0, 0.5, 1.0])
#Definition des Umfangsverhältnisses
pi = np.pi
#Anzahl der Parameterunterteilungen
n = 256
#Parameter t erstellen
t = np.linspace(-6*pi, 6*pi, n)
#Spiralgleichung
x = np.cos(t)
y = np.sin(t)
z = t
#Zeichne eine Kurve
ax.plot(x, y, z, color = "red")
plt.show()
Die Ausgabe ist wie folgt, aber ich habe eine ähnliche Zahl, obwohl es nicht funktioniert. Verschieben Sie es danach einfach und suchen Sie nach der Animation. Eine einfache Möglichkeit, eine zu finden, ist Eine animierte Handlung in 3D auf matplotlib.org, aber ich habe unten etwas näher gefunden.
【Referenz】 3D animation using matplotlib Das ist fast die Antwort.
from matplotlib import pyplot as plt
import numpy as np
import mpl_toolkits.mplot3d.axes3d as p3
from matplotlib import animation
fig = plt.figure()
ax = p3.Axes3D(fig)
def gen(n):
phi = 0
while phi < 2*np.pi:
yield np.array([np.cos(phi), np.sin(phi), phi])
phi += 2*np.pi/n
def update(num, data, line):
line.set_data(data[:2, :num])
line.set_3d_properties(data[2, :num])
N = 100
data = np.array(list(gen(N))).T
line, = ax.plot(data[0, 0:1], data[1, 0:1], data[2, 0:1])
# Setting the axes properties
ax.set_xlim3d([-1.0, 1.0])
ax.set_xlabel('X')
ax.set_ylim3d([-1.0, 1.0])
ax.set_ylabel('Y')
ax.set_zlim3d([0.0, 10.0])
ax.set_zlabel('Z')
ani = animation.FuncAnimation(fig, update, N, fargs=(data, line), interval=10000/N, blit=False)
#ani.save('matplot003.gif', writer='imagemagick')
plt.show()
Wenn ich jedoch versuche, drei Animationen zu zeichnen, sieht es so aus:
aniy = animation.FuncAnimation(fig, update, N, fargs=(datay, liney), interval=10000/N, blit=False)
anix = animation.FuncAnimation(fig, update, N, fargs=(datax, linex), interval=10000/N, blit=False)
aniz = animation.FuncAnimation(fig, update, N, fargs=(dataxy, linexy), interval=10000/N, blit=False)
Mit dieser Methode können Sie ähnliche Animationen bildlich erhalten, aber ich kann mir keine Möglichkeit vorstellen, diese drei Animationen zusammen zu speichern.
Ich beschloss, jeden von ihnen zusammen mit plt.pause (0,001) wie unten gezeigt zu zeichnen und die Abbildung zu speichern. Schließlich habe ich beschlossen, aus diesen Zahlen gif_animation zu generieren.
frames =100
s=180
for n in range(frames):
s+=1
num = s%800+200
update(num,datax,linex)
update(num,datay,liney)
update(num,dataz,linez)
plt.pause(0.001)
plt.savefig('./sin_wave/'+str(n)+'.png'.format(elev, azim))
from PIL import Image,ImageFilter
images = []
for n in range(frames):
exec('a'+str(n)+'=Image.open("./sin_wave/'+str(n)+'.png ")')
images.append(eval('a'+str(n)))
images[0].save('./sin_wave/sin_wave_el{}_az{}.gif'.format(elev, azim),
save_all=True,
append_images=images[1:],
duration=100,
loop=0)
Wenn Sie den Zeichenbereich mit line.set_data (Daten [: 2, num-200: num]) und num = s% 800 + 200 wie im folgenden Code einschränken, liegt das Ergebnis näher an Ihren Wünschen. ..
from matplotlib import pyplot as plt
import numpy as np
import mpl_toolkits.mplot3d.axes3d as p3
from matplotlib import animation
fig = plt.figure()
ax = p3.Axes3D(fig)
def genxy(n,fx,fy,fxc=0,fyc=0):
phi = 0
sk = 0
while phi < 360:
yield np.array([fx*np.cos(phi)+fxc, fy*np.sin(phi)+fyc,phi])
phi += 36*5/n
def update(num, data, line):
line.set_data(data[:2,num-200 :num]) #Begrenzen Sie den Zeichenabschnitt
line.set_3d_properties(data[2,num-200 :num])
N = 960
datay = np.array(list(genxy(N,fx=0,fy=1,fxc=-2,fyc=0))).T
liney, = ax.plot(datay[0, 0:1], datay[1, 0:1], datay[2, 0:1])
datax = np.array(list(genxy(N,fx=1,fy=0,fxc=0,fyc=2))).T
linex, = ax.plot(datax[0, 0:1], datax[1, 0:1], datax[2, 0:1])
dataz = np.array(list(genxy(N,fx=1,fy=1,fxc=0,fyc=0))).T
linez, = ax.plot(dataz[0, 0:1], dataz[1, 0:1], dataz[2, 0:1])
# Setting the axes properties
ax.set_xlim3d([-2.0,2.0])
ax.set_xlabel('X')
ax.set_ylim3d([-2.0, 2.0])
ax.set_ylabel('Y')
ax.set_zlim3d([36.0, 80.])
ax.set_zlabel('Z')
frames =36
s=180
for n in range(frames):
s+=1
num = s%800+200
update(num,datax,linex)
update(num,datay,liney)
update(num,dataz,linez)
plt.pause(0.001)
plt.savefig('./sin_wave/'+str(n)+'.png'.format(0, 0))
from PIL import Image,ImageFilter
images = []
for n in range(frames):
exec('a'+str(n)+'=Image.open("./sin_wave/'+str(n)+'.png ")')
images.append(eval('a'+str(n)))
images[0].save('./sin_wave/sin_wave_el{}_az{}.gif'.format(0, 0),
save_all=True,
append_images=images[1:],
duration=100,
loop=0)
Schreiben wir die Funktion update () wie folgt um, um die Z-Achse zu verschieben. Infolgedessen wird das Bild an derselben Position entlang der Z-Achse gezeichnet. Auch hier wird die Anzeige der Achse gelöscht.
def update(num, data, line):
line.set_data(data[:2,num-200 :num])
line.set_3d_properties(data[2,num-200 :num])
ax.set_zlim3d([0+data[2,num-200], 34+data[2,num-200]])
ax.set_zticklabels([])
ax.grid(False)
Wenn Sie die Koordinatenachsen in diese Anordnung bringen, ist sie vorerst abgeschlossen. Dies war jedoch schwierig. Zunächst können Sie die Welle wie folgt drehen. Im Folgenden wird das Bild des Anfangswertes bei geänderter Achse ausgegeben.
for elev in range(0,360,10): #Höhenänderung
for azim in range(-180,180,5): #Ändern Sie den Azimutwinkel
ax.view_init(elev, azim) #Passen Sie hier die Ausrichtung der Koordinatenachsen an
frames =1 #34
s=180
for n in range(1): #frames
s+=1
num = s%800+200
update(num,datax,linex)
update(num,datay,liney)
update(num,dataz,linez)
plt.pause(0.001)
plt.savefig('./sin_wave/'+str(n)+'{}{}.png'.format(elev, azim))
Infolgedessen wurde diese Anordnung nicht erhalten.
Sie haben nicht genug Vorstellungskraft.
Ich kann mir nichts anderes als den oben genannten Winkelbereich vorstellen.
Ich kam jedoch auf die Idee, die Achsenüberschriften für X-Y-Z zu ändern.
yield np.array([phi,fx*np.cos(phi)+fxc, fy*np.sin(phi)+fyc])
Es wird gesagt.
Mit anderen Worten, wenn Sie die Achsenrichtung ändern, legt sich die Spirale hin.
Also bin ich zu folgendem Code gekommen.
from matplotlib import pyplot as plt
import numpy as np
import mpl_toolkits.mplot3d.axes3d as p3
from matplotlib import animation
fig = plt.figure()
ax = p3.Axes3D(fig)
def genxy(n,fx,fy,fxc=0,fyc=0):
phi = 0
while phi < 360:
yield np.array([phi,fx*np.cos(phi)+fxc, fy*np.sin(phi)+fyc])
phi += 36*5/n
def update(num, data, line):
line.set_data(data[:2,num-200 :num])
line.set_3d_properties(data[2,num-200 :num])
ax.set_xlim3d([0+data[0,num-200], 36+data[0,num-200]])
ax.set_xticklabels([])
ax.grid(False)
N = 960
datay = np.array(list(genxy(N,fx=0,fy=1,fxc=-2,fyc=0))).T
liney, = ax.plot(datay[0, 0:1], datay[1, 0:1], datay[2, 0:1])
datax = np.array(list(genxy(N,fx=1,fy=0,fxc=0,fyc=-2))).T
linex, = ax.plot(datax[0, 0:1], datax[1, 0:1], datax[2, 0:1])
dataz = np.array(list(genxy(N,fx=1,fy=1,fxc=0,fyc=0))).T
linez, = ax.plot(dataz[0, 0:1], dataz[1, 0:1], dataz[2, 0:1])
# Setting the axes properties
ax.set_xlim3d([20, 70.0])
ax.set_xlabel('Z')
ax.set_ylim3d([-2.0, 2.0])
ax.set_ylabel('X')
ax.set_zlim3d([-2.0, 2.0])
ax.set_zlabel('Y')
elev=20.
azim=35.
ax.view_init(elev, azim)
frames =100
s=180
for n in range(frames): #frames
s+=1
num = s%800+200
update(num,datax,linex)
update(num,datay,liney)
update(num,dataz,linez)
plt.pause(0.001)
plt.savefig('./sin_wave/'+str(n)+'.png'.format(elev, azim))
from PIL import Image,ImageFilter
images = []
for n in range(frames):
exec('a'+str(n)+'=Image.open("./sin_wave/'+str(n)+'.png ")')
images.append(eval('a'+str(n)))
images[0].save('./sin_wave/sin_wave_el{}_az{}.gif'.format(elev, azim),
save_all=True,
append_images=images[1:],
duration=100,
loop=0)
Auf diese Weise wurde die erste veröffentlichte 3D-Animation ausgegeben.
Was ich ursprünglich machen wollte, ist eine 3D-Lisaju-Figur, also werde ich einige ausprobieren.
Sie können dies tun, indem Sie Folgendes ändern und frame = 200
ändern, damit die Verbindung reibungslos verläuft.
yield np.array([phi,fx*np.cos(3*phi/2)+fxc, fy*np.sin(2*phi/3)+fyc])
X : Y = 1 : 2 X : Y = 1/2 : 2/3 X : Y = 3/2 : 2/3
・ Ich habe eine 3D-Animation von Sin-Cos-t gezeichnet ・ Sie können jetzt 3D-Animationen zeichnen ・ Ich habe eine 3D-Lisaju-Figur gezeichnet
Abgeschlossene Version Verbessert, um Lisaju-Figur am Ursprung zu zeichnen 3d_animation_Risajyu/3D_animation_risajyu.py
Punkt hinzugefügt
Recommended Posts