2013-07-09 10 views
9

Rozważmy (Załóżmy kod działa bez błędu):Nie można zapisać matplotlib.figure rysunek, płótno jest Brak

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

teraz chcę uratować moją postać z fig.savefig(outputPath, dpi=300), ale pojawia AttributeError: 'NoneType' object has no attribute 'print_figure', ponieważ fig.canvas jest Brak. Subpoty powinny znajdować się na płótnie z cyframi, więc nie powinno to być żadne. Myślę, że brakuje mi kluczowej koncepcji o płótnach figur matowych. Jak mogę zaktualizować fig.canvas, aby odzwierciedlić obecną figurę, więc mogę użyć fig.savefig(outputPath, dpi=300)? Dzięki!

Odpowiedz

11

Jedną z rzeczy, którą robi dla ciebie plt.figure, jest dla ciebie backend, który obejmuje konfigurację kanwy. Sposób, w jaki architektura mpl to obiekty poziomu Artist, wie, jak ustawić się, upewnić się, że wszystko jest we właściwym miejscu względem siebie itd., A następnie, gdy zostanie zadane, narysuj je na płótnie. Tak więc, mimo że skonfigurowałeś partplots i linie, nie używałeś jeszcze płótna. Kiedy próbujesz zapisać figurkę, pytasz płótno, aby poprosić wszystkich artystów, aby narysowali je na nim. Nie utworzyłeś płótna (które jest specyficzne dla danego backendu), więc narzeka.

Wzorem here trzeba stworzyć płótno można osadzić w aplikacji tk (opierając się na swoim ostatnim pytaniu)

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

canvas jest Tk widget i mogą być dodawane do GUI.

Jeśli nie chcesz, aby umieścić swoją postać w Tk można użyć czystych OO metod pokazanych here (kod podnoszone bezpośrednio 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') 
+0

Dzięki to ma sens! – TheoretiCAL

1

Twój przykładowy kod nie został wypełnić mi wystarczy aby go uruchomić, aby sprawdzić moją odpowiedź, a może to zależeć od tego, jak „matfig” jest zdefiniowany, ale mam zamiar się domyślić, że to, co chcesz:

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

nie:

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

rysunek jest metodą modułu, do której należy wywołać/wywołać.

Rysunek jest kontenerem najwyższego poziomu dla wszystkich elementów fabuły, choć jest nieco bardziej skomplikowany.

+0

Jeśli spojrzysz na swoje poprzednie pytanie, to spróbuje to zrobić bez użycia 'pyplot' – tacaswell

+0

import matplotlib.figure jako matfig, jak stwierdził tcaswell, przepisuję mój kod pyplot na rysunek i nie byłem pewien jak tłumaczyć to completelty – TheoretiCAL

+0

Nie widziałem innego pytania TheoretiCAL, aby zapewnić dodatkowy kontekst na temat tego, co jest naprawdę potrzebne.Właśnie odpowiedziałem, jak pozbyć się komunikatu o błędzie savefig "NoneType", który pokazuje powyżej w oparciu o jego instrukcję "Załóżmy, że kod działa bez błędu". Moja odpowiedź dotyczy tego ograniczonego stwierdzenia problemu, z którym wcześniej się spotkałem. – cloudpoint

0

Program Matplotlib może być bardzo mylący.

Co lubię robić, to używać metody figure(), a nie metody Figure(). Ostrożnie z wielką literą. W poniższym przykładowym kodzie, jeśli masz figure = plt.Figure(), dostaniesz błąd, który jest w pytaniu. Używając funkcji figure = plt.figure(), płótno jest tworzone dla ciebie.

Oto przykład, który obejmuje również małą ciekawostkę dotyczącą zmiany rozmiaru obrazu, ponieważ potrzebna jest również pomoc w tym zakresie.

################################# 
# 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() 
Powiązane problemy