0

I have an implicit function, say x**2 - y = 0 (to simplify), of which I want to obtain a plot for a certain range of x values.

sympy.plot_implicit usually gives some spreading of the lines that I am not happy with.

I would like to have access to the plotted values, and so pyplot.plot is preferable to me. Usually I use the following piece of code to get my explicit Sympy functions plotted, but I am unsure how to use something similar for exp = sym.Eq(x**2 - y, 0). Does anyone have a solutions for this?

import sympy as sym
import numpy as np
from matplotlib import pyplot as plt

x, y = sym.symbols('x y', nonnegative=True)
exp = x**2

# Plot using a numpy-ready function
x_arr = np.linspace(-2, 2, 100)
exp_func = sym.lambdify(x, exp, 'numpy')
exp_arr = exp_func(x_arr)

plt.plot(x_arr, exp_arr)

PS: my real expression is b_sim (see below) and I want the plot for the equation b_sim = -1. With sym.plot_implicit(b_sim + 1, (n,0.225,1.5), (h, -1.1, 1.1)) one can see the lines spreading I dislike. Following Oscar Benjami's tips here, I attempted the following piece of code that is giving an error for roots.

from sympy import *

h, nu = symbols('h nu', nonnegative=True) 
b_sim = 1.0*cos(pi*sqrt(1 - h)/(2*nu))*cos(pi*sqrt(h + 1)/(2*nu)) - 1.0*sin(pi*sqrt(1 - h)/(2*nu))*sin(pi*sqrt(h + 1)/(2*nu))/sqrt(1 - h**2)

eq = Eq(b_sim + 1, 0) 
sols = roots(eq, h) 
sym.plot(*sols, (nu, 0.225, 1.5), ylim=(-1.1, 1.1))

2 Answers 2

2

The line spread of plot_implicit is caused by the adaptive algorithm. If you set the option adaptive=False the plotting module would use a meshgrid approach. However, due to the implementation, the figure is likely not going to be good (too much "segmentation").

This is how you can do it with Numpy and Matplotlib:

import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import numpy as np

expr = eq.rewrite(Add)
f = lambdify([nu, h], expr)
n = 2000j
nnu, hh = np.mgrid[0.225:1.5:n, -1.1:1.1:n]
res = f(nnu, hh)

plt.figure()
cmap = ListedColormap(["tab:blue", "tab:blue"])
plt.contour(nnu, hh, res, levels=[0], cmap=cmap)
plt.show()

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

-1

To have access to the plotted values of a sympy function plot, in this case the coordinates of lines2d plot, is simple.

Here is the code that plots the function.

import matplotlib.pyplot as plt
from sympy import symbols
import numpy as np
import sympy

x, y = symbols('x y', nonnegative=True)
exp = x**2

# Plot using a numpy-ready function
x_arr = np.linspace(-2, 2, 10)  #small number for demo
exp_func = sympy.lambdify(x, exp, 'numpy')
exp_arr = exp_func(x_arr)

plt.figure(figsize=(4, 3))
lines2d = plt.plot(x_arr, exp_arr)

parabola1

In the code above, lines2d is a list of line2d objects. To get the coordinates from the 1st (only one in this case), do this:

xys = lines2d[0].get_xydata()

And you can use it to plot with this code:-

fig = plt.figure(figsize=(4, 3))
ax = fig.add_subplot()
ax.plot(xys[:,0], xys[:,1])

1 Comment

This code was given in the problem statement as applicable to an explicit function y = x^2. In that case the points plotted are simply (x_arr, exp_arr). The question is how to adapt this piece of code for an implicit function x^2 - y = 0 (assume in the real world you cannot isolate y on the l.h.s.).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.