0

Consider this code:

fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.gca()

ax.text(0.0,0.0,"Test", fontsize=45)
ax.axis('off')
canvas.draw()       # draw the canvas, cache the renderer
width, height = fig.get_size_inches() * fig.get_dpi()
images = np.fromstring(canvas.tostring_rgb(), dtype='uint8').reshape(int(height), int(width), 3)

So the problem I have, is that it saves the plot with a text "Test" on it. But suppose I have a plot, "AxesImages" matplotlib to be precise, how can I convert the image plot instead of the text? I have tried to change the ax.text(...) with ax.imshow(axesImage) but it threw and error.

Any suggestions?

1 Answers1

1

You could save the image to a file and then load the file into an array using PIL:

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

fig, ax = plt.subplots()
ax.text(0.0,0.0,"Test", fontsize=45)
ax.axis('off')
ax.imshow(np.random.random((3,3)))
filename = '/tmp/out.png'
fig.savefig(filename)
img = Image.open(filename).convert('RGB')
arr = np.asarray(img)
img.show()

enter image description here

If you wish to avoid disk I/O, you could save the image to a BytesIO object instead:

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

fig, ax = plt.subplots()
ax.text(0.0,0.0,"Test", fontsize=45)
ax.axis('off')
ax.imshow(np.random.random((3,3)))

with io.BytesIO() as memf:
    fig.savefig(memf, format='PNG')
    memf.seek(0)
    img = Image.open(memf)
    arr = np.asarray(img)
    img.show()
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • Yes I know about this method but the problem is that I need to convert 51k images for the NN and it takes ages to first save them. What is the advantage of saving BytesIO? Does it compute faster? –  Nov 23 '17 at 11:59
  • Disk I/O can be [orders of magnitude slower](http://norvig.com/21-days.html#answers) than memory I/O. So using `BytesIO` would be faster, though processing 51K images would probably still take a lot of time. – unutbu Nov 23 '17 at 12:03
  • I see, that makes sense. So where can I obtain those images after saving them? I am sorry, I do not have experience with ByteIO and wondering where exactly does it save. Also, the arr shows all the values to be 255, is that correct? –  Nov 23 '17 at 12:12
  • That one is funny :-) – ImportanceOfBeingErnest Nov 23 '17 at 12:13
  • @ImportanceOfBeingErnest funny? –  Nov 23 '17 at 12:14
  • The whole point of a buffer is that the image is not saved to disk, so you will not find it on disk. – ImportanceOfBeingErnest Nov 23 '17 at 12:18
  • @ImportanceOfBeingErnest Well I know that, but what is the point of saving as bytes if there is no way of obtaining it? I was thinking to save as arrays but it returns 255 for all values, which is surely incorrect and wonder why –  Nov 23 '17 at 12:21
  • @ImportanceOfBeingErnest I guess my Smart Pants does not know the answer, funny :) –  Nov 23 '17 at 12:43
  • In my code above, the image is stored in a NumPy array called `arr`. The `BytesIO` object is `memf`. Its only purpose (above) is to facilitate the creation of `arr`. `arr` contains other values besides 255. (Evaluate `np.where(arr != 255)` to see where.) The reason why you are seeing so many 255's is because the image contains a white border. To remove the white border, see [here](http://stackoverflow.com/a/4328608/190597) or [here](http://stackoverflow.com/q/8218887/190597). – unutbu Nov 23 '17 at 12:59
  • I think it is still a bit unclear what you are trying to achieve. This answer here does its best at answering the question, but if it doesn't, it's not so much the fault of the answerer, but rather the question not being clear enough. – ImportanceOfBeingErnest Nov 23 '17 at 13:51