12

考虑(假设代码运行没有错误):

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

我现在想用 保存我的身材fig.savefig(outputPath, dpi=300),但我得到了AttributeError: 'NoneType' object has no attribute 'print_figure',因为fig.canvas没有。子图应该在图形画布上,所以它不应该是无。我想我错过了一个关于 matplot 数字画布的关键概念。如何更新 fig.canvas 以反映当前的数字,所以我可以使用fig.savefig(outputPath, dpi=300)?谢谢!

4

3 回答 3

16

为您做的一件事是plt.figure为您处理后端,其中包括设置画布。mpl 的架构方式是Artist关卡对象知道如何设置自己,确保所有东西相对于彼此都在正确的位置等,然后当被问到时,将它们自己绘制到画布上。因此,即使您已经设置了子图和线条,您还没有真正使用过画布。当您尝试保存图形时,您是在要求画布要求所有艺术家在其上绘制自己。您尚未创建画布(特定于给定后端),因此它会抱怨。

按照此处的示例,您需要创建一个可以嵌入到 tk 应用程序中的画布(从上一个问题开始)

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

canvas是一个Tk小部件,可以添加到 gui。

如果您不想将图形嵌入其中,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')
于 2013-07-09T03:35:04.727 回答
2

Matplotlib 可能非常令人困惑。

我喜欢做的是使用 figure() 方法而不是 Figure() 方法。小心大小写。在下面的示例代码中,如果您有 figure = plt.Figure() 您将收到问题中的错误。通过使用 figure = plt.figure() 为您创建画布。

这是一个示例,其中还包含一些关于重新调整图像大小的花絮,因为您也需要这方面的帮助。

#################################
# 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()
于 2017-06-27T18:36:01.150 回答
1

您的示例代码不够完整,我无法运行它来验证我的答案,它可能取决于“matfig”的定义方式,但我猜你想要的是:

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

不是:

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

figure 是您应该调用/调用的模块方法。

Figure 是所有绘图元素的顶级容器,尽管它比这更复杂一些。

于 2013-07-09T03:51:50.543 回答