Search code examples
pythonmatplotlibsympy

Why am I getting different plots for each run of same Python SymPy plotting code?


My code (Linux Mint 21.2, Python 3.10):

import sympy
print(sympy.__version__) # '1.9'
from sympy import symbols, sin
from sympy.plotting import plot
t = symbols('t')
plotP = plot(  50*sin(t/30)+30*sin(1.3*t/30)+20*sin(2.7*t/30)+25*sin(3.7*t/30), (t, 24800 , 35800) )

Four different runs, four different plots:

[Plot_1 Plot_2 Plot_1 Plot_4

What could be the reason for getting this confusing results?

============

ADDED to clarify that the issue occurs also when the script is executed from a shell:

Plot_5

============

ADDED to show that upgrading to newest versions of sympy and matplotlib did not solve the issue:

Plot_6

By the way: I can't reproduce the issue with much smaller intervals like for example 0 to 400 - in this case the diagrams are all the same. The difference: the "steady" diagrams consist of a nice smooth curve without overlapping peaks because of putting a very large interval with peaks much nearer to each other than the distance of the pixels in the display.


Solution

  • Next to the issue with adaptive=True ( the weird behavior actually disappears with adaptive=False ) mentioned already in the comments to your question :

    The randomness in explicitly mentioned in the sympy plotting docs. "The plotting uses an adaptive algorithm which samples recursively to accurately plot the curve. The adaptive algorithm uses a random point near the midpoint of two points that has to be further sampled. Hence, repeating the same plot command can give slightly different results because of the random sampling." – JohanC Feb 9 at 12:19

    you become a victim of a probably widespread wrong beginner expectation that the shape of the plot you see has always something to do with the shape of the function you are plotting.

    This expectation is the main reason why you were surprised to see some strange artifacts in the periodic sinus function plots like straight lines over a longer period of time and in combination with the adaptive algorithm used in sympy for choosing the sampling points you experienced random changes of the plotted curve, which was not the expected representation of the underlying function values, but some kind of random result depending on choice of the section on time axis anyway.

    In other words, YOU have the responsibility to know that if you use a fast changing periodic function of t and use then a too large timeline period, what you see in the plot, even if it looks like a periodic curve, is nothing else as some by chance of choosing the start and end time obtained more or less arbitrary values connected to each other to form a curve in the plot. So what you actually see in the plot has as good as nothing to do with the actual shape of the curve of the function you are plotting.

    I encourage you to play with nb_of_points parameter you can pass to the plot method. The lower the assigned to it value, like for example: nb_of_points=7 the more what you see has as good as nothing to do with the function you are plotting. In other words you will be getting very different plots depending on the value you use for nb_of_points. Try it out and see for yourself.

    Below an example of using your code with different values for nb_of_points= to illustrate the above explanations:

    Plot_51-52__59

    Further reading: Smoothing sympy plots