Reputation: 47
I have been trying of solving an implicit equations using contour plot but I realized it was taking into account the singularities of my equation so I was obtaining wrong graphs. Because of this, I tried sympy.plot_implicit. Fortunately, it works properly but I have not found a proper way to set a label on the graphs produced by sympy.plot_implicit. For this aim, I need to obtain the points used by sympy.plot_implicit for producing its the graphs and use them into matplotlib. This way, I am obtainig correct solutions for my implicit equations and I can easily set labels for the graphs of the solutions. At this moment, I am facing many issues when I try to obtain the point from sympy.plot_implicit, I mean, when I only use sympy.plot
there is not any problem but the issues appear when I use sympy.plot_implicit
.
I have attached the code, thank you in advance.
Best
import matplotlib.pyplot as plt
import sympy as sp
from sympy.abc import x,y,z
def z(x, y):
return x - y
line = sp.plot(x**2,(x,-1,0), show=False)
#line = sp.plot_implicit(z(x, y), (x, 0, 1), (y, 0, 1), show=False)
x, y = line[0].get_points()
plt.plot(x, y)
plt.show()
Upvotes: 0
Views: 1179
Reputation: 80509
You can use the move_sympyplot_to_axes
function from Display two Sympy plots as two Matplotlib subplots, adapting one line as explained in its comments.
To get something in the legend, matplotlib's standard approach is to add a label to the specific element. In this case, the implicit area seems to be stored as a polygon inside ax.patches
. Such a polygon will be shown as a colored rectangle in the legend. In order to get a line, a custom legend element could be created.
As in this case the solution is represented as a thin polygon and not as a line p1[0].get_points()
doesn't work. However, you can extract the polygon's vertices from the matplotlib polygon patch:
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
import sympy as sp
from sympy.abc import x, y, z
def move_sympyplot_to_axes(p, ax):
backend = p.backend(p)
backend.ax = ax
backend._process_series(backend.parent._series, ax, backend.parent)
backend.ax.spines['right'].set_color('none')
backend.ax.spines['top'].set_color('none')
backend.ax.spines['bottom'].set_position('zero')
plt.close(backend.fig)
def z(x, y):
return (x ** 2 + y ** 2 - 1) ** 3 - x ** 2 * y ** 3
p1 = sp.plot_implicit(z(x, y), (x, -1.5, 1.5), (y, -1.5, 1.5), show=False)
fig, ax = plt.subplots()
move_sympyplot_to_axes(p1, ax)
# ax.patches[0].set_label("my label")
handles = [Line2D([], [], color=ax.patches[0].get_facecolor())]
ax.legend(handles=handles, labels=["my label"], loc='upper left')
vertices = ax.patches[0].get_path().vertices
ax.plot(vertices[:, 0], vertices[:, 1], ls=':', color='gold', lw=10, alpha=0.5, zorder=0)
plt.show()
Upvotes: 1