import math
from math import pi as pi
from math import cos as cos
from math import sin as sin
import matplotlib
from matplotlib import colormaps as CM
from matplotlib.animation import FuncAnimation as FA
from matplotlib.patches import Polygon as mpP
import matplotlib.pyplot as plt
import numpy as np
#10 viridis colors
cmap = CM.get_cmap('viridis_r')
v = [plt.cm.colors.rgb2hex(cmap(i)) for i in np.linspace(0, 1, 10)]
#Clear axes.
def clearAx(ax):
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["bottom"].set_visible(False)
ax.spines["left"].set_visible(False)
ax.set_xticks([])
ax.set_yticks([])
return(ax)
#Pentagon layout.
labels = []
xs = []
ys = []
for i in range(5):
#5 vertices of pentagon.
m = 2*pi*i/5
x = cos(pi/2 + m)
y = sin(pi/2 + m)
#Label locations.
labels.append([(1.2*x, 1.2*y), 180*m/pi])
for j in range(4):
#4 points around main vertices. To allow clear visual of path.
n = 2*pi*j/4
x = x + 0.05*cos(pi/4 + m + n)
y = y + 0.05*sin(pi/4 + m + n)
#5*4 = 20 vertices.
xs.append(x)
ys.append(y)
#Pentagon labels.
text0 = [("Rock", labels[0][0], labels[0][1]),
("Lizard", labels[1][0], labels[1][1]),
("Spock", labels[2][0], labels[2][1]),
("Scissors", labels[3][0], labels[3][1]),
("Paper", labels[4][0], labels[4][1])]
#Path indices.
indices = [[2, 5, 9, 13, 17, 0, 15, 7, 19, 11, 2], #R
[1, 5, 9, 13, 16, 11, 3, 15, 7, 18, 1], #P
[1, 5, 9, 12, 7, 19, 11, 3, 14, 17, 1], #Sc
[1, 5, 8, 3, 15, 7, 19, 10, 13, 17, 1], #Sp
[2, 4, 19, 11, 3, 15, 6, 9, 13, 17, 0], #L
[2, 4, 18, 0, 15, 6, 9, 13, 16, 11, 2], #L-R-P
[2, 5, 9, 12, 7, 18, 0, 14, 16, 11, 2], #R-P-Sc
[1, 5, 8, 3, 14, 16, 10, 12, 7, 18, 1], #P-Sc-Sp
[1, 4, 19, 11, 12, 6, 8, 3, 14, 17, 1], #Sc-Sp-L
[2, 4, 19, 10, 13, 17, 0, 15, 6, 8, 2], #Sp-L-R
[2, 4, 18, 0, 14, 16, 10, 12, 6, 8, 2]] #R-P-Sc-Sp-L
def pathCreator(o, k) :
if o > 9 :
z = str(o) + str(k)
else :
z = "0" + str(o) + str(k)
fig = plt.figure(figsize = (8, 8))
ax = fig.add_subplot(xlim = (-1.3, 1.3),
ylim = (-1.3, 1.3))
ax = clearAx(ax)
for t in (text0) :
plt.annotate(text = t[0],
xy = t[1],
c = 'k',
size = 30,
ha = 'center',
va = 'center',
rotation = t[2])
px = []
py = []
for i in range(11):
j = indices[o][i]
px.append(xs[j])
py.append(ys[j])
if i > 0:
plt.quiver(px[i-1],
py[i-1],
px[i]-px[i-1],
py[i]-py[i-1],
color = v[i-1-k],
scale_units = 'xy',
angles = 'xy',
scale = 1,
lw = 2)
#Traversal Number.
plt.annotate(text = z,
xy = (1.25, 1.2),
c = 'k',
size = 30,
ha = 'right',
va = 'bottom')
#Save
fig.savefig("./anim/2024.09.27-" + z + ".png", bbox_inches = 'tight')
for o in range(11) :
for k in range(10) :
plt.ioff()
pathCreator(o, k)
import os
import moviepy.video.io.ImageSequenceClip
image_folder = './anim'
fps = 2
image_files = [os.path.join(image_folder,img)
for img in os.listdir(image_folder)
if img.endswith(".png")]
clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(image_files, fps=fps)
clip.write_videofile('2024.09.27-ALL.mp4')
C:\Users\rohan\AppData\Local\Temp\ipykernel_19948\66677623.py:8: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`). Consider using `matplotlib.pyplot.close()`. fig = plt.figure(figsize = (8, 8))
Moviepy - Building video 2024.09.27-ALL.mp4. Moviepy - Writing video 2024.09.27-ALL.mp4
Moviepy - Done ! Moviepy - video ready 2024.09.27-ALL.mp4