Davide-sd / sympy-plot-backends

An improved plotting module for SymPy
BSD 3-Clause "New" or "Revised" License
44 stars 10 forks source link

Make scatter points plot using Sympy plot backends #28

Closed faze-geek closed 1 year ago

faze-geek commented 1 year ago

Hi @Davide-sd, I was exploring the sympy plotting module and tried to start with basic scatter plot to link lists of x and y values equivalent to this -

import matplotlib.pyplot as plt

# Sample data
x_data = [2, 3, 4, 5]
y_data = [5, 6, 7, 10]

# Create a scatter plot
plt.scatter(x_data, y_data)

According to https://github.com/sympy/sympy/issues/19263, this is not supported yet . Also I could not find anything in the documentation. Is this possible with the new sympy-plot-backends project?

Davide-sd commented 1 year ago

Hello @faze-geek , take a look at the plot_list function.

faze-geek commented 1 year ago

Thanks a lot it works. Continuing a query on this issue itself, I want to add the x and y axis to my scatter plot. I tried this as done with matplotlib.

    if show_axes:
        plot.axhline = 0
        plot.axvline = 0

It doesn't return an error but it doesn't give me the axes as well. Could you help me here.

faze-geek commented 1 year ago

Update: Went through the documentation a bit but couldn't figure out the axes.

Sympy's axis_center = 'center' highlights the axis but does not result in a good plot in my opinion. I would prefer the equivalent of Matplotlib's :

        plt.axhline = 0
        plt.axvline = 0

@Davide-sd Sorry if this is naive, but would really like your guidance here.

Davide-sd commented 1 year ago

What you are doing is overwriting Matplotlib's axhline function with the number zero.

This is the documentation of Matplotlib's axhline.

What you have to do is something like this:

plt.axhline(y=0)
plt.axvline(x=0)
faze-geek commented 1 year ago

Yes you are right. I have used this while using Matplotlib independently. I just don't get how to inculcate it with the Matplotlib backend used by sympy-plot-backends. I tried something like this, before making the comment -

>>> from sympy import *
>>> from spb import plot_list
>>> x = [1, -2, 3]
>>> y = [2, 5, -6]
>>> p = plot_list(x, y,is_point = True)
>>> fig = p.fig
>>> ax  = fig.axes[0]
>>> ax.axhline(0, color='black')
<matplotlib.lines.Line2D object at 0x000001D548687D30>
>>> ax.axvline(0, color='black')
<matplotlib.lines.Line2D object at 0x000001D547F631F0>

Not sure if it is even possible.

faze-geek commented 1 year ago

If you can suggest any method (Matplotlib's axhline for axis isn't a hard requisite) for clear axes with the scatter plot , that would be helpful as well. Thanks in advance !

Davide-sd commented 1 year ago

The module is built on the concept that there exists an appropriate renderer for each data series. So, if you'd like to change the way something is displayed, you'd have to redefine a renderer.

List2DSeries (used by plot_list) is rendered with Line2DRenderer. We have to modify it to also show one horizontal black line, and one vertical black line.

from spb import *
from spb.backends.matplotlib.renderers.line2d import (
    Line2DRenderer, _draw_line2d_helper, _update_line2d_helper
)
from spb.series import List2DSeries

def new_draw_method(renderer, data):
    # add one horizontal line, and one vertical line
    p = renderer.plot
    p.ax.axhline(0, color="k")
    p.ax.axvline(0, color="k")
    # draw everything else as before
    return _draw_line2d_helper(renderer, data)

Line2DRenderer.draw_update_map = {
    new_draw_method: _update_line2d_helper
}

x = [1, -2, 3]
y = [2, 5, -6]
p = plot_list(x, y,is_point = True)

image

faze-geek commented 1 year ago

Thanks a lot !