pythonsympy

Why does sympy.plot_implicit() not work for combined conditionals that involve sympy.Abs()?


I have the following python code that uses sympy:

from sympy import *
x, y = symbols('x y')

cond1 = y + 2*Abs(x) > 0
cond2 = x > 0
cond3 = y < 0

p1 = plot_implicit(cond1)
p2 = plot_implicit(cond2)
p3 = plot_implicit(And(cond2, cond3))
try:
    p4 = plot_implicit(And(cond1, cond2))
except:
    print("Why is this not working")

The last plot throws, but I don't know why.

The example here (plot two implicit functions with plot_implicit) is very similar and just works.


Solution

  • I'm the developer of SymPy Plotting Backends, which provides improved plotting functions in comparison to what SymPy offers. After your comment above, I solved the bug and created a new release with the fix, which is already available on PyPi and should become available on Conda in a couple of days.

    Here is the code and the results:

    from sympy import *
    from spb import *
    var("x y")
    cond1 = y + 2*Abs(x) > 0
    cond2 = x > 0
    cond3 = y < 0
    
    expr = And(cond1, cond2)
    p1 = plot_implicit(cond1, x, y, n=101, grid=False, title=str(cond1))
    p2 = plot_implicit(cond2, x, y, grid=False, title=str(cond2))
    p3 = plot_implicit(expr, x, y, n=1001, grid=False, title=str(expr))
    

    results of the code

    When you execute the code above, you'll see a couple of warnings when creating p3:

    UserWarning: The provided expression contains Boolean functions. In order to plot the expression, the algorithm automatically switched to an adaptive sampling.
    UserWarning: Adaptive meshing could not be applied to the expression. Using uniform meshing.
    

    plot_implicit implements two evaluation algorithms:

    1. an adaptive algorithm, which uses interval arithmetic.
    2. an ordinary evaluation over a uniform mesh of points.

    Usually, SymPy Plotting Backend's plot_implicit uses the second algorithm. When it receives a boolean expression (containing And, Or) it automatically switches to the first algorithm, because it usually produces better results (according to my tests). However, your expression contains Abs, which the adaptive algorithm is unable to evaluate. The code detects this event, and attempts to evaluate the expression with the second algorithm.

    Now, take a look at the line of code producing p1. I specified the expression to be plotted, and the order of the variables (x is going to be on the x-axis, y is going to be on the y-axis). I have not specified ranges, so plot_implicit will limit x and y between -10 and 10. I have used n=101 (odd number): in doing so the meshing will place a discretization point both at x=0 and y=0, thus producing a better looking plot. The same is true for p3, in which an increased number of discretization points is required in order to produce a better looking plot.

    If you'll find other bugs please open an issue at this Github repository.