-1

There I created an animation using celluloid library. This animation shows the point which move along the elliptical line. The problem is that, when I run this code, everything is working in sublime text, but when I use Jupyter, it outputs error. How can I solve this problem? You can see my code in the answers.

 import math
 import numpy as np
 import matplotlib.pyplot as plt
 from celluloid import Camera
 import copy

 img = np.ones((90,60,3))
 fig = plt.figure(figsize=(10,8), dpi = 100, facecolor='w')

 camera = Camera(fig)
 quarterCircleOne = []
 quarterCircleTwoHalfOne = []
 quarterCircleTwoHalfTwo = []
 quarterCircleThree = []
 quarterCircleFourHalfOne = []
 quarterCircleFourHalfTwo = []

xc = 45
yc = 30
rx = 25
ry = 15
def GenerateElipse(xc,yc,rx,ry):
    img[xc, yc] = (255,0,0)
    img[xc+1, yc] = (255,0,0)
    img[xc-1, yc] = (255,0,0)
    img[xc, yc+1] = (255,0,0)
    img[xc, yc-1] = (255,0,0)
    xk = 0
    yk = ry
    pk = ry**2 -rx**2 * ry+1/4* rx**2

    while ry**2 * xk < rx**2 *yk:
        if pk>0:
            xk = xk+1
            yk = yk-1
            pk = pk + 2 * ry**2 *xk + ry**2 - 2* rx**2 *yk
        else:
            xk = xk+1
            pk=pk + 2* ry**2 * xk + ry**2
        img[xc+xk, yc+yk] = (0,0,0)
        img[xc+xk, yc-yk] = (0,0,0)
        img[xc-xk, yc+yk] = (0,0,0)
        img[xc-xk, yc-yk] = (0,0,0)
        quarterCircleOne.append([xc-xk, yc-yk])
        quarterCircleTwoHalfTwo.append([xc-xk, yc+yk])
        quarterCircleThree.append([xc+xk, yc+yk])
        quarterCircleFourHalfOne.append([xc+xk, yc-yk])

    pk = ry**2 * (xk-1/2)**2 + rx**2 * (yk-1)**2 - rx**2 * ry**2

    while yk>0:
        if pk>0:
            yk = yk-1
            pk=pk -2 * rx**2 * yk + rx**2
        else:
            xk = xk+1
            yk = yk-1
            pk=pk - 2 * rx**2 * yk +  2* ry**2 *xk + rx**2
        img[xc+xk, yc+yk] = (0,0,0)
        img[xc+xk, yc-yk] = (0,0,0)
        img[xc-xk, yc+yk] = (0,0,0)
        img[xc-xk, yc-yk] = (0,0,0)
        quarterCircleOne.append([xc-xk, yc-yk])
        quarterCircleTwoHalfOne.append([xc-xk, yc+yk])
        quarterCircleThree.append([xc+xk, yc+yk])
        quarterCircleFourHalfTwo.append([xc+xk, yc-yk])

  GenerateElipse(45, 30, 25, 15)


  def DrawElipse(speed, img):
     sortedQuarterCircleOne = sorted(quarterCircleOne,key=lambda x: x[1])
     sortedQuarterCircleTwoHalfOne = 
     sorted(quarterCircleTwoHalfOne,key=lambda x: x[1])
     sortedQuarterCircleTwoHalfTwo = 
     sorted(quarterCircleTwoHalfTwo,key=lambda x: x[0])
     sortedQuarterCircleThree = sorted(quarterCircleThree,key=lambda x: x[1], 
     reverse=True)
     sortedQuarterCircleFourHalfTwo = 
     sorted(quarterCircleFourHalfTwo,key=lambda x: x[1], reverse=True)
     sortedQuarterCircleFourHalfOne = 
     sorted(quarterCircleFourHalfOne,key=lambda x: x[0], reverse=True)

     circle = [sortedQuarterCircleOne, sortedQuarterCircleTwoHalfOne, 
   sortedQuarterCircleTwoHalfTwo, sortedQuarterCircleThree, 
   sortedQuarterCircleFourHalfTwo, sortedQuarterCircleFourHalfOne]

i = 0
for x in range(0, 6):
    for coordinates in circle[x]:
        freshImage = copy.deepcopy(img)
        freshImage[coordinates[0], coordinates[1]] = (0,0,0)
        freshImage[coordinates[0], coordinates[1]+1] = (255,0,0)
        freshImage[coordinates[0], coordinates[1]-1] = (255,0,0)
        freshImage[coordinates[0]+1, coordinates[1]-1] = (0,0,255)
        freshImage[coordinates[0]+1, coordinates[1]+1] = (0,0,255)
        freshImage[coordinates[0]+1, coordinates[1]] = (255,0,0)
        freshImage[coordinates[0]-1, coordinates[1]-1] = (0,0,255)
        freshImage[coordinates[0]-1, coordinates[1]+1] = (0,0,255)
        freshImage[coordinates[0]-1, coordinates[1]] = (255,0,0)
        if i % speed == 0:
            plt.imshow(freshImage)
            camera.snap()
        i = i + 1
DrawElipse(1, img);
animation = camera.animate()
plt.show()

enter image description here

1 Answers1

1

The "error" Clipping input data to the valid range... stems from the data you give to plt.imshow. It hints that you should supply data within [0..255] for integers e.g. np.uint8 and [0..1] for floating point types e.g. np.float32. Check your input data, and clip it beforehand if necessary, or cast it to the right datatype, e.g. plt.imshow(np.uint8(freshImage)).

That error is not what makes the animation not show up; it's an error provided by matplotlib's imshow. It will actually do its best to render the image despite the problem in the input range.

To see the animation use this in the end (in a Jupyter notebook, remember to from IPython.display import HTML):

animation = camera.animate()
HTML(animation.to_html5_video())

As per the documentation for Celluliod: https://github.com/jwkvam/celluloid

Roy Shilkrot
  • 3,079
  • 29
  • 25