How do I draw a graph in a loop so that the graph of the previous cycle remains in the drawing? (matplotlib)
I started learning python quite recently, as it is convenient to draw 3D graphics with matplotlib (you need it for a diploma). So far I'm trying to draw a 2d graph, but I have two windows at the end of the program showing no graph (empty axes). Where can there be a mistake? How can I make the loop draw a graph in one window and complement the previous graph?
import numpy as np
import math
from classes import Point
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import axes3d
# Инициализируем данные
eps: float = float(1/100)
h: float = float(0.0001)
t: float = float(30)
a: int = -10
b: int = 10
xmi = -15
ymi = -15
xma = 15
yma = 15
N: int = 0
# Глобальные переменные (массивы)
OTX = [0]*100
OTY = [0]*100
OTZ = [0]*100
X1 = [0]*100
X2 = [0]*100
Y1 = [0]*100
Y2 = [0]*100
Z1 = [0]*100
Z2 = [0]*100
# Объявили функции
def f1(x, y, z, t):
return ((float)(y - pow(x, 3) / 3.0 + x)) / eps
def f2(x, y, z, t):
return -x + z
def f3(x, y, z, t):
return x*y
def f(x):
return (float)(pow(x, 3) / 3.0 - x)
def rungeKutta():
i=0
while i < N:
OTX[i] = float(input("x{0} = ".format(i + 1)))
OTY[i] = float(input("y{0} = ".format(i + 1)))
OTZ[i] = float(input("z{0} = ".format(i + 1)))
i += 1
i = 0
while i < N:
X1[i] = OTX[i]
Y1[i] = OTY[i]
Z1[i] = OTZ[i]
i += 1
qX1 = 0
qX2 = 0
qX3 = 0
qY1 = 0
qY2 = 0
qY3 = 0
qZ1 = 0
qZ2 = 0
qZ3 = 0
j: int = 0
plt.ion()
while j < N:
ansX = []
ansY = []
ansZ = []
time = 0
while time < t:
if abs(X1[j]) < 10000 and abs(Y1[j]) < 10000:
qX1 = h * f1(X1[j], Y1[j], Z1[j], time)
qY1 = h * f3(X1[j], Y1[j], Z1[j], time)
qZ1 = h * f1(X1[j], Y1[j], Z1[j], time)
qX2 = h * f1(X1[j] + qX1 / 2, Y1[j] + qY1 / 2, Z1[j] + qZ1 / 2, time + h / 2)
qY2 = h * f2(X1[j] + qX1 / 2, Y1[j] + qY1 / 2, Z1[j] + qZ1 / 2, time + h / 2)
qZ2 = h * f3(X1[j] + qX1 / 2, Y1[j] + qY1 / 2, Z1[j] + qZ1 / 2, time + h / 2)
qX3 = h * f1(X1[j] - qX1 + 2 * qX2, Y1[j] - qY1 + 2 * qY2, Z1[j] - qZ1 + 2 * qZ2, time + h)
qY3 = h * f2(X1[j] - qX1 + 2 * qX2, Y1[j] - qY1 + 2 * qY2, Z1[j] - qZ1 + 2 * qZ2, time + h)
qZ3 = h * f3(X1[j] - qX1 + 2 * qX2, Y1[j] - qY1 + 2 * qY2, Z1[j] - qZ1 + 2 * qZ2, time + h)
X2[j] = X1[j] + (qX1 + 4 * qX2 + qX3) / 6
Y2[j] = Y1[j] + (qY1 + 4 * qY2 + qY3) / 6
Z2[j] = Z1[j] + (qZ1 + 4 * qZ2 + qZ3) / 6
ansX.append(X2[j])
ansY.append(Y2[j])
ansZ.append(Z2[j])
time += h
j += 1
plt.plot(ansX, ansY)
plt.draw()
plt.pause(0.1)
plt.ioff()
plt.show()
# Начало программы
N = int(input("Введите количество точек (N): "))
rungeKutta()
I had other rendering options (already 3d) like this:
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_wireframe(X, Y, Z, rstride=8, cstride=8, alpha=0.5)
ax.set_xlim(-40, 40)
ax.set_ylim(-40, 40)
ax.set_zlim(-100, 100)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()
Where X Y Z is the ansX ansY ansZ from the code higher. But I do not know how to draw again in a loop. Please tell me, I couldn't find anything that worked
1 answers
You have several questions mixed up in one question at once. This is wrong. Let's take turns. So the question is "How to draw a graph in a loop so that the graph of the last cycle remains in the figure? (matplotlib)"
Answer:
Trivial scatter-plot
x=[]
y=[]
fig,ax=plt.subplots()
ax.axis([0, 1, 0, 1])
for i in range(200):
ax.cla()
x.append(random.random())
y.append(random.random())
ax.scatter(x, y)
plt.pause(0.05)
Trivial graph (with accumulation)
x=[]
y=[]
fig,ax=plt.subplots()
ax.axis([0, 1, 0, 1])
for i in range(200):
ax.cla()
x.append(i)
y.append(random.random())
ax.plot(x,y)
plt.pause(0.05)
This is so that you understand what is drawn and how, understand the principle and can quickly tweak something in your script. In t th number, rendering in a loop. Hope for the first "trial" with the topic is enough for you.
However, I must say right away, this method is not quite correct.
Animated Feng shui graphs should be drawn using the FuncAnimation function of the matplotlib.animation package.