简体   繁体   English

无法保存matplotlib.figure图中,canvas为None

[英]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. 我现在想用fig.savefig(outputPath, dpi=300)保存我的图,但是我得到了AttributeError: 'NoneType' object has no attribute 'print_figure' ,因为fig.canvas是None。 The sub plots should be on the figures canvas, so it shouldn't be None. 子图应该在图形画布上,因此它不应该是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) ? 我想我错过了一个关于matplot数字画布的关键概念。我如何更新fig.canvas以反映当前的图,所以我可以使用fig.savefig(outputPath, dpi=300) Thanks! 谢谢!

One of the things that plt.figure does for you is wrangle the backend for you, and that includes setting up the canvas. plt.figure为你做的事情之一plt.figure为你plt.figure后端,包括设置画布。 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. mpl的体系结构的方式是Artist级别的对象知道如何设置自己,确保一切都在相对于彼此的正确位置等,然后当被问及时,将它们自己绘制到画布上。 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) 按照此处的示例您需要创建一个可以嵌入tk应用程序的画布(从上一个问题开始)

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

canvas is a Tk widget and can be added to a gui. canvas是一个Tk小部件,可以添加到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): 如果您不想在Tk嵌入您的图形,您可以使用此处显示的纯OO方法(代码直接从链接中提取):

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')

Your sample code wasn't complete enough for me to run it to verify my answer, and it might depend on how 'matfig' is defined, but I'm going to guess that what you want is: 您的示例代码不够完整,我无法运行它来验证我的答案,这可能取决于'matfig'的定义方式,但我猜你想要的是:

fig = matfig.figure(figsize=(16.8, 8.0))

not: 不:

fig = matfig.Figure(figsize=(16.8, 8.0))

figure is the module method that you should invoke/call. figure是您应该调用/调用的模块方法。

Figure is the top level container for all the plot elements, though it's bit more complicated than this. 图是所有绘图元素的顶级容器,尽管它比这更复杂。

Matplotlib can be very confusing. Matplotlib可能非常令人困惑。

What I like to do is use the the figure() method and not the Figure() method. 我喜欢做的是使用figure()方法而不是Figure()方法。 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. 在下面的示例代码中,如果你有figure = plt.Figure(),你将得到问题中的错误。 By using figure = plt.figure() the canvas is created for you. 通过使用figure = plt.figure(),可以为您创建画布。

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM