Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to save matplotlib.figure Figure, canvas is None

Consider (Assume code runs without error):

import matplotlib.figure as matfig

    ind = numpy.arange(N)
    width = 0.50;
    fig = matfig.Figure(figsize=(16.8, 8.0))
    fig.subplots_adjust(left=0.06, right = 0.87)
    ax1 = fig.add_subplot(111)
    prev_val = None
    fig.add_axes(ylabel = 'Percentage(%)',xlabel='Wafers',title=title,xticks=(ind+width/2.0,source_data_frame['WF_ID']))
    fig.add_axes(ylim=(70,100))

    for key,value in bar_data.items():
        ax1.bar(ind,value, width,color='#40699C', bottom=prev_val)
        if prev_val:
            prev_val = [a+b for (a,b) in zip(prev_val,value)]
        else:
            prev_val=value

    names= []
    for i in range(0,len(col_data.columns)):
        names.append(col_data.columns[i])
    ax1.legend(names,bbox_to_anchor=(1.15, 1.02))

I now want to save my figure with fig.savefig(outputPath, dpi=300), but I get AttributeError: 'NoneType' object has no attribute 'print_figure', because fig.canvas is None. The sub plots should be on the figures canvas, so it shouldn't be None. I think i'm missing a key concept about matplot figures canvas.How can I update fig.canvas to reflect the current Figure, so i can use fig.savefig(outputPath, dpi=300)? Thanks!

like image 340
TheoretiCAL Avatar asked Jul 09 '13 00:07

TheoretiCAL


People also ask

How do I save a figure in matplotlib?

Saving a plot on your disk as an image file Now if you want to save matplotlib figures as image files programmatically, then all you need is matplotlib. pyplot. savefig() function. Simply pass the desired filename (and even location) and the figure will be stored on your disk.

Why is %Matplotlib inline?

%matplotlib inline turns on “inline plotting”, where plot graphics will appear in your notebook. This has important implications for interactivity: for inline plotting, commands in cells below the cell that outputs a plot will not affect the plot.

What is figure canvas matplotlib?

FigureCanvas is the area onto which the figure is drawn, the matplotlib. backend_bases. Renderer is the object which knows how to draw on the FigureCanvas , and the matplotlib.

How do I save a matplotlib file as a JPEG?

To save plot figure as JPG or PNG file, call savefig() function on matplotlib. pyplot object. Pass the file name along with extension, as string argument, to savefig() function.


2 Answers

One of the things that plt.figure does for you is wrangle the backend for you, and that includes setting up the canvas. The way the architecture of mpl is the Artist level objects know how to set themselves up, make sure everything is in the right place relative to each other etc and then when asked, draw them selves onto the canvas. Thus, even though you have set up subplots and lines, you have not actually used the canvas yet. When you try to save the figure you are asking the canvas to ask all the artists to draw them selves on to it. You have not created a canvas (which is specific to a given backend) so it complains.

Following the example here you need to create a canvas you can embed in your tk application (following on from your last question)

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
canvas = FigureCanvasTkAgg(f, master=root)

canvas is a Tk widget and can be added to a gui.

If you don't want to embed your figure in Tk you can use the pure OO methods shown here (code lifted directly from link):

from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure

fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
ax.plot([1,2,3])
ax.set_title('hi mom')
ax.grid(True)
ax.set_xlabel('time')
ax.set_ylabel('volts')
canvas.print_figure('test')
like image 95
tacaswell Avatar answered Sep 17 '22 15:09

tacaswell


Matplotlib can be very confusing.

What I like to do is use the the figure() method and not the Figure() method. Careful with the capitalization. In the example code below, if you have figure = plt.Figure() you will get the error that is in the question. By using figure = plt.figure() the canvas is created for you.

Here's an example that also includes a little tidbit about re-sizing your image as you also wanted help on that as well.

#################################
# Importing Modules
#################################
import numpy
import matplotlib.pyplot as plt


#################################
# Defining Constants
#################################
x_triangle = [0.0, 6.0, 3.0]
y_triangle = [0.0, 0.0, 3.0 * numpy.sqrt(3.0)]
x_coords = [4.0]
y_coords = [1.0]
big_n = 5000
# file_obj = open('/Users/lego/Downloads/sierpinski_python.dat', 'w')
figure = plt.figure()
axes = plt.axes()



#################################
# Defining Functions
#################################
def interger_function():
    value = int(numpy.floor(1+3*numpy.random.rand(1)[0]))
    return value


def sierpinski(x_value, y_value, x_traingle_coords, y_triangle_coords):
    index_for_chosen_vertex = interger_function() - 1
    x_chosen_vertex = x_traingle_coords[index_for_chosen_vertex]
    y_chosen_vertex = y_triangle_coords[index_for_chosen_vertex]
    next_x_value = (x_value + x_chosen_vertex) / 2
    next_y_value = (y_value + y_chosen_vertex) / 2
    return next_x_value, next_y_value



#################################
# Performing Work
#################################

for i in range(0, big_n):
    result_from_sierpinski = sierpinski(x_coords[i], y_coords[i], x_triangle, y_triangle)
    x_coords.append(result_from_sierpinski[0])
    y_coords.append(result_from_sierpinski[1])

axes.plot(x_coords, y_coords, marker = 'o', color='darkcyan', linestyle='none')
plot_title_string = "Sierpinski Gasket with N = " + str(big_n)
plt.title(plot_title_string)
plt.xlabel('x coodinate')
plt.ylabel('y coordinate')
figure.set_figheight(10)
figure.set_figwidth(20)
file_path = '{0}.png'.format(plot_title_string)
figure.savefig(file_path, bbox_inches='tight')
plt.close()
# plt.show()
like image 33
Russell Lego Avatar answered Sep 16 '22 15:09

Russell Lego