How do I use the markers parameter of a sympy plot?

Nice find!

The documentation doesn’t make things clear. Diving into the source code, leads to these lines in plot.py:

            for marker in parent.markers:
                # make a copy of the marker dictionary
                # so that it doesn't get altered
                m = marker.copy()
                args = m.pop('args')
                ax.plot(*args, **m)

So, sympy just calls matplotlib’s plot with:

  • the args key of the dictionary as positional parameters
  • all the other keys of the dictionary as keyword parameters

As matplotlib’s plot allows a huge variety of parameters, they all are supported here. They are primarily meant to show extra markers onto the plot (you need to give their positions).

An example:

from sympy import symbols, sin, plot

x = symbols('x')
plot(sin(x), markers=[{'args': [2, 0, 'go']},
                      {'args': [[1, 3], [1, 1], 'r*'], 'ms': 20},
                      {'args': [[2, 4, 6], [-1, 0, -1], ], 'color': 'turquoise', 'ls': '--', 'lw': 3}])

These get converted to:

ax.plot(2, 0, 'go')  # draw a green dot at position 2,0
ax.plot([3, 5], [1, 1], 'r*', ms=20)  # draw red stars of size 20 at positions 3,1 and 5,1
ax.plot([2, 4, 6], [-1, 0, -1], ], color="turquoise", ls="--", lw=3)
    # draw a dotted line from 2,-1  over 4,0 to 6,-1

using markers in sympy's plot

PS: The source code shows a similar approach for dictionaries with annotations, rectangles and fills (using plt.fillbetween()):

        if parent.annotations:
            for a in parent.annotations:
                ax.annotate(**a)
        if parent.rectangles:
            for r in parent.rectangles:
                rect = self.matplotlib.patches.Rectangle(**r)
                ax.add_patch(rect)
        if parent.fill:
            ax.fill_between(**parent.fill)

Leave a Comment