0

I came across python behavior that I would like to understand. Take a look at the following lines.

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0,1,100)
plt.plot(x, x, 'k', color=None)
plt.plot(x, x**2, 'k', color=None)

According to the matplotlib documentation the plot-kwargs are defined in the Line2D class. There, we find that color takes 'None' as default argument. Hence the plot ought to be black and white. However, the output is colorful.

enter image description here

If I remove the optional color argument, I get black lines. So my question is, why is the above plot colored, even though I passed None as a color-option?

Edit: I understand that removing color=None leads to 'k' being used as the color option. However, I would like to understand how matplotlib internally can distuingish between

plt.plot(x, x, 'k', color=None)

and

plt.plot(x, x, 'k')

if the color argument is None by default. (Which it is according to the documentation.)

4
  • 1
    Having None as the default argument indicates to matplotlib that a value for the color argument was not specified, so default values are used. It is not for disabling colour. Commented Jul 11, 2017 at 10:48
  • I still don't understand how that is possible in python. Say, I define a function def foo(a=None). I don't see how it could be possible to find out weather I call it as foo() or foo(a=None). But apparently, matplotlib can distinguish between these two calls as it shifts from colorful to black and white. Do you know why? Commented Jul 11, 2017 at 10:59
  • 2
    It depends how the function is written. If the function is def foo(a=None) then yes, the two calls are equivalent. If instead it is defined as def foo(**kwargs), kwargs will be an empty dictionary for foo(), and {'a': None} for foo(a=None). The behaviour is then up to how the function handles kwargs Commented Jul 11, 2017 at 11:33
  • Thanks, I understand now. Commented Jul 11, 2017 at 12:42

2 Answers 2

3

In plt.plot(x, x, 'k', color=None), you have two color definitions. The first is the positional argument 'k' (black), the second is the keyword argument color=None.

If you leave out the color=None, the positional argument 'k' will be used and the lines will be black. No supprise here.

If you specify color=None, it will overwrite the 'k' argument. Thus color=None will determine the color and that means a color is chosen according to the current color cycle.

To answer the question on how it is possible to distinguish the cases:

First let me note that the way matplotlib manages arguments and keyword arguments to finally decide upon the properties of the lines is rather complex. To see what actually happens, you may start at the plot function and follow the arguments through the various functions and classes. To explain everything here would be too much, so let's look at an example of how it could be done in a simplified way.

The plot method does not look like def plot(x,y,something, color=None), but simply def plot(*args,**kwargs).

Therefore color is not an argument, but a keyword argument. A way the two color arguments could be disinguished would e.g. look like

def plot(*args,**kwargs):
    x = args[0]
    y = args[1]
    if len(args) > 2:
        color = args[2]
    else:
        color = None
    color = kwargs.get("color", color)
    print color

plot([1,2],[3,4], "k", color=None) # prints None
plot([1,2],[3,4], "k")             # prints k
plot([1,2],[3,4], color=None)      # prints None
plot([1,2],[3,4])                  # prints None
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, that is indeed true. However, I still don't understand how that is possible in python, see the comment to my question.
Yes, that is exactly what I was looking for. Thank you.
3

The Parameter 'k' is the color abbreviation for the color black. But when you set color=None it overrides black with None which means matplotlib will use default colors.

matplotlib will then automatically cycle through colors. By default, it cycles through blue, green, red, cyan, magenta, yellow, black.

Edit: In matplotlib 2.0 default color cycle has been changed: source

1 Comment

Thanks, that is indeed true. However, I still don't understand how that is possible in python, see the comment to my question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.