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>
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?
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.
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>
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()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.