1

I want to get a matplotlib figure as a 3 dimensional RGBA array. I'm using the following code to do the conversion:

%matplotlib inline

import matplotlib.pyplot as plt
import numpy as np

canvas = np.zeros((20, 20))

img = plt.imshow(canvas, interpolation='none').make_image()
h, w, d = img.as_rgba_str()
print(h,w)
rgba_array = np.fromstring(d, dtype=np.uint8).reshape(h, w, 4)

plt.imshow(rgba_array)

Out[1]: (249, 373)
<matplotlib.image.AxesImage at 0x111fa8b10>

output from cell

Why the aspect ratio changes from the original square array? Is there any parameter that I can specify or an alternative method to get the figure's rgba array in its original shape?

3 Answers 3

1

I think you can get there using this answer: https://stackoverflow.com/a/35362787/1072212, but instead of canvas.tostring_rgb() use canvas.tostring_argb() (not ..._rgba()), and

width, height = map(int, fig.get_size_inches() * fig.get_dpi())
image = image.reshape(height, width, 4)
image = np.roll(image, -1, 2)

later you might want

img = Image.fromarray(image, 'RGBA')
img.save('my.png')
img.show()
Sign up to request clarification or add additional context in comments.

Comments

0

when I execute your code in pycharm (353, 497) when I execute your code in pycharm line by line (353, 353) when I execute your code in ipython (from command shell) (385, 497)

I suppose the

img = plt.imshow(canvas, interpolation='none').make_image()
h, w, d = img.as_rgba_str()

make_image() is actually not transforming the values, BUT one value for each pixel in the axes. So if your axes are shown as a square on the screen it picks a square at a higher resolution. Otherwise just some rectangle, depending on your backend and screen resolution.

Comments

0

I've found an alternative method which doesn't make use of the .imshow() function and that preserves size ratio:

%matplotlib inline

import matplotlib.pyplot as plt
import numpy as np
from PIL import Image

canvas = np.zeros((20, 20))
img = Image.fromarray(np.uint8(plt.cm.gist_earth(canvas)*255))
rgba_array = np.array(img.getdata(), np.uint8).reshape(img.size[1], img.size[0], 4)
print(rgba_array.shape)

plt.imshow(rgba_array)

Out[1]: (20, 20, 4)
<matplotlib.image.AxesImage at 0x112a71710>

enter image description here

Comments

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.