[PYTHON] [Einführung in Matplotlib] Achsen 3D-Animation: Ich habe mit 3D-Lisaju-Figuren gespielt ♬

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.

Was ich getan habe

・ Axes3D-Animation ・ Sin-Cos-t-Animation

・ Axes3D-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. Figure_helix.png Eine einfache Möglichkeit, eine zu finden, ist Eine animierte Handlung in 3D auf matplotlib.org, aber ich habe unten etwas näher gefunden.

・ Sin-Cos-t-Animation

【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()

matplot003.gif 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.

- Rufen Sie die Funktion update () direkt zum Zeichnen auf

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. .. sin_wave_el0_az0.gif

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)    

・ Verschieben Sie die Z-Achse

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)

sin_wave_el0_az0.gif

・ Drehung der Figuren

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.

・ 3D Lisaju Figur

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 sin_wave1-2_el20.0_az35.0.gif X : Y = 1/2 : 2/3 sin_wave1w2-2w3_el20.0_az35.0.gif X : Y = 3/2 : 2/3 sin_wave3w2-2w3-2_el20.0_az35.0.gif

Zusammenfassung

・ Ich habe eine 3D-Animation von Sin-Cos-t gezeichnet ・ Sie können jetzt 3D-Animationen zeichnen ・ Ich habe eine 3D-Lisaju-Figur gezeichnet

Bonus

Abgeschlossene Version Verbessert, um Lisaju-Figur am Ursprung zu zeichnen 3d_animation_Risajyu/3D_animation_risajyu.py

Punkt hinzugefügt sin_wave_point_el20.0_az35.0.gif

Recommended Posts

[Einführung in Matplotlib] Achsen 3D-Animation: Ich habe mit 3D-Lisaju-Figuren gespielt ♬
[Einführung in Pytorch] Ich habe mit sinGAN ♬ gespielt
[Einführung in StyleGAN] Ich habe mit "The Life of a Man" ♬ gespielt
[Einführung in sinGAN-Tensorflow] Ich habe mit der hochauflösenden "Challenge Big Imayuyu" ♬ gespielt
[Einführung in RasPi4] Ich habe mit "Hiroko / Hiromis giftigem Zungengespräch" gespielt ♪
[Einführung in StyleGAN] Ich habe mit "Eine Frau verwandelt sich in Mayuyu" gespielt ♬
Wie man mit matplotlib mehrere Figuren betitelt
[Einführung in AWS] Ich habe mit Polly und Transcribe male mit Männer- und Frauenstimmen gespielt
[Einführung in StyleGAN] Ich habe mit style_mixing "Frau, die die Brille abnimmt" ♬ gespielt
Animation mit matplotlib
Animation mit matplotlib
Ich möchte mehrere Bilder mit matplotlib anzeigen.
Ich wollte die 3D-Partikelsimulation mit der Python-Visualisierungsbibliothek Matplotlib visualisieren.
Ich habe mit Wordcloud gespielt!
[Einführung in den Systemhandel] Ich habe einen Stochastic Oscillator mit Python gezeichnet und damit gespielt ♬
[Einführung in Pytorch] Ich habe versucht, Cifar10 mit VGG16 ♬ zu kategorisieren
Ich möchte manuell eine Legende mit matplotlib erstellen
3D-Plot mit Matplotlib
[Python] So erstellen Sie mit Matplotlib ein zweidimensionales Histogramm
[Einführung in AWS] Ich habe versucht, mit der Sprach-Text-Konvertierung zu spielen ♪
Stellen Sie die Achsen mit matplotlib ein
[IOS] GIF-Animation mit Pythonista3. Ich war süchtig danach.
Ich habe eine Animation gemacht, die Othellos Stein mit POV-Ray zurückgibt
Einführung in RDB mit sqlalchemy Ⅰ
Einführung in die nichtlineare Optimierung (I)
Ich las "Das Lernen mit Python von der Einführung bis zur Praxis stärken", Kapitel 1
Ich wollte das ABC164 A ~ D-Problem mit Python lösen
[Einführung] Ich möchte mit Python einen Mastodon-Bot erstellen! 【Anfänger】
Ich las "Das Lernen mit Python von der Einführung bis zur Praxis stärken", Kapitel 2
Erstellen Sie eine Plotanimation mit Python + Matplotlib
Einführung in RDB mit sqlalchemy II
Ich habe mit PyQt5 und Python3 gespielt
Ich möchte ○○ mit Pandas machen
Ich habe mit Mecab gespielt (morphologische Analyse)!
Zeichnen Sie einfach Diagramme mit matplotlib
Ich möchte mit Python debuggen
Einfache Animation mit matplotlib (mp4, gif)
(Matplotlib) Ich möchte ein Diagramm mit einer in Pixel angegebenen Größe zeichnen
Ich habe versucht, fMRI-Daten mit Python zu analysieren (Einführung in die Dekodierung von Gehirninformationen)