Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plotting issue (matplotlib): "ValueError: posx and posy should be finite values"

I solved a problem that I couldn't find on stackoverflow, so I decided to upload it for others that encounter the error.

I have a set of functions to create a video from different plots. I use this to for example show how positions ([X Y] coordinates) change over time.

Inside one of my plotting procedures (see "a_plotting_function" in the example code), I used matplotlib's "text" to add text to a plot. However, in some cases, it resulted in an error:

"ValueError: posx and posy should be finite values"

The error appears at "writer.grab_frame()", which gave me a hard time locating the actual error.

In the example code, the error is perhaps easy to spot: the X value for one of the to-be-plotted coordinates is set to np.nan.

This bug was particularly difficult to catch because 1) the actual plotting procedure I use is much more complicated (or: more difficult to read) and 2) the error doesn't point at the cause (which turns out to be "plt.text", which makes posx and posy infinite for some reason..).

I hope I saved someone else the effort of finding the cause at some point in the future!

import matplotlib.pyplot as plt
import matplotlib.animation as manimation
import numpy as np

def a_plotting_function(X, Y, dX, dY, print_string):

    plt.plot([X-dX, X], [Y-dY, Y])
    plt.text(X, Y, print_string)

X = 0
Y = 0

dX = 1
dY = 2

frames = 30
frameRate = 24
dpi = 300

print_string = 'poetry'

writer = manimation.FFMpegWriter(fps = frameRate, extra_args=['-pix_fmt', 'yuv420p'])

fig, ax = plt.subplots()

ax.set_xlim((X, X + frames * dX))
ax.set_ylim((Y, Y + frames * dY))

with writer.saving(fig, 'my_beautiful_movie.mp4', dpi):

    for frame in range(frames):

        X += dX
        Y += dY

        if X > 0.7 * frames:
            X = np.nan

        a_plotting_function(X, Y, dX, dY, print_string)

        writer.grab_frame()

ValueError: posx and posy should be finite values [Finished in 2.7s with exit code 1] [shell_cmd: python -u "stack_overflow\value_error_matplotlib.py"]

like image 633
Rens Avatar asked Aug 27 '19 12:08

Rens


1 Answers

The answer (as partly explained in the post) is that matplotlib's "text" sets posx and posy to infinite if the coordinates are "np.nan". This doesn't get noticed at the moment that you're plotting it, but only when grabbing the frame to the writer object.

So: avoid making an infinitely large plot by not having any of the coordinates (for matplotlib's text) be np.nan.

like image 193
Rens Avatar answered Jan 01 '23 22:01

Rens