Just to expand on what @Yann already said:
To understand why this happens, you need to understand a little about the structure of matplotlib. To enable "matlab-isms" like plt.setp and maintain compatibility with older versions of python, matplotlib avoids properties and relies heavily on getters and setters. ( plot is actually one of the most difficult cases, simply because of all the crazy calling forms that it supports).
You can make a good argument that this is an outdated, non-reptile design, but that is irrelevant.
What actually happens (for the simplest case, plot(x, y, other=stuff) ) when plot is called is that a new matplotlib.line.Line2D object is created from the first two arguments, and then matplotlib.line.Line2D.update(kwargs) is matplotlib.line.Line2D.update(kwargs) .
update basically:
for key, value in kwargs.iteritems(): func = getattr(self, 'set_'+key) func(value)
I simplify too much, but this is the main idea.
Also, the accepted keyword argument list is basically auto- set_* from everything that has set_* . Because Line2D has the set_xdata and set_ydata , they appear in the keyword argument list.
The fact is that keyword arguments are never used until after more initialization of Line2D , and if you do not specify any arguments, plot will not initialize any Line2D .
You may consider this a mistake, but I doubt it will be fixed. I do not think that xdata and ydata were ever intended to be used as keyword arguments.
set_xdata and set_ydata so you can quickly update an instance of Line2D instead of creating a new one (for animation, etc.). They are simply allowed as keyword arguments due to the way matplotlib is configured.