Matplotlib interfering with NumPy (on Windows)

Viewed 646

The issue described below has been replicated


Say you have the following
import numpy as np
import matplotlib.pyplot as plt

x = np.random.randint(5, size=(100, 12), dtype=np.int64)
# [THERE IS ACTUALLY NO NEED TO SET THE DATA TYPE
# `x = np.random.rand(100, 12)` yields the same problem]

and you want to compute x's rank.

>>> np.linalg.matrix_rank(x)
12

Everything is fine. Let's restart a new session from scratch, whose underlying code this time is

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(1010)  # <-----
x               = np.random.randint(5, size=(100, 12), dtype=np.int64)
x_vals = y_vals = np.arange(0, .5, .05)

plt.plot(x_vals, y_vals, linestyle='--')

print(np.linalg.matrix_rank(x))

This prints 0 (!!). And more surprisingly, the reason behind this is the value given to linestyle (!!). I mean, having linestyle='-' (solid) turns everything back to normal.

This is clearly an undesired behavior (I literally spent hours to locate precisely)... but still:

How ?


This occurs under Windows 10 with Python3.7.3
numpy==1.19.2      # since 1.19.0 actually
matplotlib==3.3.3  # between 3.1.3 and 3.3.3 for what I can tell

No problem under Linux (with the same environment)


Other precisions
  1. This does not occur for all x's shape. Hard to tell exactly. However, this is not random either, and is monotonously linked to x's (vertical and/or horizontal) shape.
  2. The issue is transposition-invariant.
  3. x is exactly the same when compared to itself before plt.plot is called (compared using joblib.hash)

enter image description here


This question is more about leaving a trace than getting an answer. This is so weird that I had to write it somewhere. I've changed my linestyle...

The title of the question is sufficiently unequivocal to drive people with the same problem as mine here.


Another screen capture:

enter image description here

The GIF's code follows.

import numpy as np
import matplotlib.pyplot as plt
import joblib as jl

linestyles = [
    'solid', '-',
    'dotted',  # '.', => ValueError: '.' 
    'dashed', '--',
    'dashdot', '-.',
    ':', '', ' '    
]

for ls in linestyles:
    print(26*'*', f"linestyle='{ls}'")
    
    np.random.seed(1010)
    x  = np.random.rand(9, 5)
    h0 = jl.hash(x)
    
    x_vals = y_vals = np.arange(0, .5, .05)
    plt.plot(x_vals, y_vals, linestyle=ls)
    # plt.show()
    
    h1 = jl.hash(x)
    mr = np.linalg.matrix_rank(x)
    print(
        '\t', mr, (not mr)*'<---------------[!!!]'
    )
    print('\t', 'Has not changed:', h0 == h1)
1 Answers

I had a similar problem in the past too (basically matplotlib not performing as expected).

This was my question: python plotting chart in interactive viewer vscode

Basically, the way the plot is called and when it is finished this is deleted: "if you close the figure, you're essentially deleting it".

I tend to use the interactive environment (using python 3.10 in VScode on windows 10) and this works:

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(1010)  # <-----
x = np.random.randint(5, size=(100, 12), dtype=np.int64)
x_vals = y_vals = np.arange(0, .5, .05)

x = np.linalg.matrix_rank(x)
print(x)

plt.plot(x_vals, y_vals, linestyle='-')
plt.show()

and i get this result (which behaves well):

12

enter image description here

Related