Search code examples
pythonmatplotlibhashcryptographyhashlib

Using hashlib on a matplotlib object


Using Python, I am trying to write tests that compare the current output with an expected output. The output is a matplotlib figure and I would like to do this without saving the figure to a file.

I had the idea to find the cryptographic hash of the object so that I would just need to compare one hash with another to confirm that the entire object is unchanged from what is expected.

This works fine for a numpy array as follows:

import numpy as np
import hashlib
np.random.seed(1)
A = np.random.rand(10,100)
actual_hash = hashlib.sha1(A).hexdigest()
expected_hash = '38f682cab1f0bfefb84cdd6b112b7d10cde6147f'
assert actual_hash == expected_hash

When I try this on a matplotlib object I get: TypeError: object supporting the buffer API required

import hashlib
import numpy as np
import matplotlib.pyplot as plt
X = np.linspace(0,100,1000)
Y = np.sin(0.5*X)
plt.plot(X,Y)
fig = plt.gcf()
actual_hash = hashlib.sha1(fig).hexdigest() #this raises the TypeError

Any ideas how I can use hashlib to find the cryptographic hash of a matplotlib object?

Thanks.


Solution

  • You can get the figure as a numpy array using buffer_rgba(). Before using it you must actually draw the figure:

    draw must be called at least once before this function will work and to update the renderer for any subsequent changes to the Figure.

    import hashlib
    import numpy as np
    import matplotlib.pyplot as plt
    X = np.linspace(0,100,1000)
    Y = np.sin(0.5*X)
    plt.plot(X,Y)
    canvas = plt.gcf().canvas
    canvas.draw()
    
    actual_hash = hashlib.sha1(np.array(canvas.buffer_rgba())).hexdigest()