Or, why doesn't
import numpy
import matplotlib.pyplot as plt
plt.plot(xdata = numpy.array([1]), ydata = numpy.array(1), color = 'red', marker = 'o')
work? c.f.
> In [21]: import numpy
> In [22]: import matplotlib.pyplot as plt
> In [23]: plt.plot(xdata = numpy.array([1]), ydata = numpy.array(1), color = 'red', marker = 'o')
> Out[23]: []
> In [24]: plt.plot([1],[1], color = 'red', marker = 'o')
> Out[24]: [<matplotlib.lines.Line2D at 0x108036890>]
> In [25]: plt.plot(1, 1, color = 'red', marker = 'o')
> Out[25]: [<matplotlib.lines.Line2D at 0x1041024d0>]
Just to expand on what @Yann already said:
To understand why this happens, you need to understand a bit more about matplotlib's structure. To allow "matlab-isms" like plt.setp
, and to maintain compatibility with older versions of python, matplotlib avoid properties and relies heavily on getters and setters. (plot
is actually one of the most complex cases, simply due to all of the crazy forms of calling it supports.)
You can make a good argument that this is an outdated, unpythonic design, but that's beside the point.
What actually happens (for the simplest case of plot(x, y, other=stuff)
) when you call plot
is that a new matplotlib.line.Line2D
object is created from the first two arguments, and then matplotlib.line.Line2D.update(kwargs)
is called.
update
basically does:
for key, value in kwargs.iteritems():
func = getattr(self, 'set_'+key)
func(value)
I'm over-simplifying, but that's the basic idea.
Also the accepted keyword argument list is basically auto-generated from anything that has a set_*
. Because Line2D
has set_xdata
and set_ydata
methods, they show up in the keyword argument list.
The point is, that the keyword arguments are never actually used until after most of the initialization of Line2D
, and if you don't specify any arguments, plot
won't initialize any Line2D
's.
You could consider this a bug, but I doubt it would be fixed. I don't think xdata
and ydata
were ever intended to be used as keyword arguments.
set_xdata
and set_ydata
are there to allow you to quickly update a Line2D
instance instead of creating a new one (For animations, etc...). They just happen to be allowed as keyword arguments due to the way matplotlib is set up.
Why? Who knows, but it appears a line is not created unless you define x
and y
arguments. xdata
and ydata
change the data of the line only if it is created, and it seems it is not created without the parameters. Try this:
plt.plot([0],[0],xdata = [1,2,3,4], #numpy.array([3,4]),
ydata = [4,5,6,7], #numpy.array([3,4]),
color = 'red',
marker = 'o')
It works as I think you intend it to.