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
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)