Combine sympy and matplotlib plots in one picture
Asked Answered
N

3

7

I need to build an expression graph and a graph set by an array of points, and return the images. To build an expression graph, I use sympy.plot, and to build a graph on points I use matplotlib.

Here is an example code:

from os import remove
from matplotlib import pyplot as plt
from PIL import Image
from sympy import plot, symbols

def plot_graphic(x, y, expression, file_name):
    file = '{}.png'.format(file_name)
    x1, y1 = list(x), list(y)
    plt.plot(x1, y1)
    plt.savefig(file)
    plt.close()
    del y1
    img = Image.open(file)
    remove(file)
    yield img

    x = symbols('x')
    plot(expression.args[1], (x, x1[0], x1[-1]), show=False).save(file)
    img = Image.open(file)
    remove(file)
    yield img

x, y are generators. How can I combine these images at one?

Newspaper answered 25/5, 2018 at 16:26 Comment(7)
I'm going to guess that sympy.plot is using MatPlotLib to do the actual work here.Laurettelauri
I did not find in the sympy documentation how to build a graph of the given pointsNewspaper
i was going the other way with that. It looks like sympy.plot returns a regular MatPlotLib figure that you can use to add whatever plots you want additionallyLaurettelauri
sympy.plot returns a Plot object and I can not build it using matplotlib.Newspaper
The second sentence at docs.sympy.org/latest/modules/plotting.html reads "Presently the plots are rendered using matplotlib as a backend"Laurettelauri
I'm unclear as to how to get a reference to said backend from reading the docs though, so good question. I'll do some more research and let you know if I find anything.Laurettelauri
@MadPhysicist See also #46811380 (including the comment by Sébastien Loisel)Badly
N
1

I found a solution. Sympy has a method for plotting points. You need to create a List2DSeries object that does the necessary and add to the other graphics using the append method. The resulting code is shown below.

from os import remove
from PIL import Image
from sympy import plot, symbols
from sympy.plotting.plot import List2DSeries

def plot_graphic(x, y, expression, file_name):
    file = '{}.png'.format(file_name)
    x1, y1 = list(x), list(y)
    x = symbols('x')
    graph = plot(expression.args[1], (x, x1[0], x1[-1]), show=False, line_color='r')
    graph.append(List2DSeries(x1, y1))
    graph.save(file)
    img = Image.open(file)
    remove(file)
    return img
Newspaper answered 26/5, 2018 at 11:16 Comment(1)
But can I use this method to add the separate points of another look/color, say red points, to the previously created graph p1 drawn with blue line?Discommodity
P
1

There is a solution using the get_points() function in sympy. Here is an example for plotting two sets of data using Matplotlib

plots = sympy.plot(data0, data1, show=False)
for plot in plots:
   pts = plot.get_points()
   plt.plot(pts[0], pts[1])
plt.show()

You can also set all the parameters of plt, like axis limit and legend.

Pastoralize answered 3/11, 2021 at 23:44 Comment(1)
This didn't work for me when trying to get the points from a plot_implicit() plot. I got lists containing some kind of interval object.Speaker
E
0

sympy.plot has undocomunted arguments fig,ax that would take an existing matplotlib's figure and fill it with data (starting from sympy version 1.13).

import matplotlib.pyplot as plt
import sympy

fig, ax = plt.subplots()
ax.plot([-2,-1,0,1,2], [4.1,0.9,0.1,1.1,3.8])

x = sympy.symbols('x')
sympy.plot(x**2, (x,-2,2), fig=fig, ax=ax)
Eurystheus answered 8/3, 2024 at 8:5 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.