2

I am trying to convert a bar chart figure into a numpy array. I am doing so using the code below:

df = pd.DataFrame.from_dict(data)    

fig = plt.figure()
fig.add_subplot(1, 1, 1)

df.plot.bar()

plt.savefig('curr_bar_chart.png')

numpy_array = fig2data(fig)
plt.close()
im = data2img(numpy_array)

At the end of the question I also attach the code for fig2data and data2img.

My problem: The image that is saved (curr_bar_chart.png) shows up fine, but when viewing the final image using im.show() I get a plot without any data (i.e. empty plot with axes).

This is very puzzling since this setup works for me for other matplotlib plots that I am using elsewhere.

As promised, the rest of the code:

 def fig2data(fig):
    """
    @brief Convert a Matplotlib figure to a 4D numpy array with RGBA channels and return it
    @param fig a matplotlib figure
    @return a numpy 3D array of RGBA values
    """
    # draw the renderer
    fig.canvas.draw()

    # Get the RGBA buffer from the figure
    w, h = fig.canvas.get_width_height()
    buf = np.fromstring(fig.canvas.tostring_argb(), dtype=np.uint8)
    buf.shape = (w, h, 4)

    # canvas.tostring_argb give pixmap in ARGB mode. Roll the ALPHA channel to have it in RGBA mode
    buf = np.roll(buf, 3, axis=2)
    return buf

def data2img ( data ):
    """
    @brief Convert a Matplotlib figure to a PIL Image in RGBA format and return it
    @param fig a matplotlib figure
    @return a Python Imaging Library ( PIL ) image
    """
    # put the figure pixmap into a numpy array
    w, h, d = data.shape
    return Image.frombytes( "RGBA", ( w ,h ), data.tostring( ) )

1 Answer 1

1

That is because your fig is indeed empty. You can see this by plt.show() in place of plt.savefig('curr_bar_chart.png'):

df = pd.DataFrame.from_dict(data)    

fig = plt.figure()
fig.add_subplot(1, 1, 1)

df.plot.bar()

plt.show()

You would end up seeing two figures and this first one (empty) is your fig. To fix this, you can pass the axes of fig to pandas bar plot. You would then get one single plot, which is your fig:

df = pd.DataFrame.from_dict(data)    

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

df.plot.bar(ax = ax)

plt.savefig('curr_bar_chart.png')

numpy_array = fig2data(fig)
plt.close()
im = data2img(numpy_array)
im.show()
Sign up to request clarification or add additional context in comments.

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.