wyklad7 Python


Programowanie Fizyka Medyczna
Wykład VII
8 maja 2012
Ściąga z obsługi plików
Przypomnienie modułu Matplotlib:

Klasa Figure i moduł matplotlib.figure

Klasa Axes i moduł matplotlib.axes

Klasa Line2D i moduł matplotlib.lines

Klasa Annotate i moduł matplotlib.text
Tkinter  proste okienka w Pythonie
Ściąga z obsługi plików
Podstawą czytania i zapisywania do dowolnego pliku jest utworzenie obiektu, który będzie
go reprezentował w programie  tzw. "uchwytu" (handle).
fp = open('nazwapliku', 'rb') # tworzy obiekt fp, przez który następuje odwołanie do pliku
Wszystkie operacje na pliku dokonywane są poprzez metody związane z obiektem fp.
'nazwapliku'  jest nazwą pliku
'rb' tryb dostępu do pliku. Składa się maksymalnie z 3 grup znaków:
['r'  odczyt | 'w'  zapis | 'a'  append/dopisanie]
['b'  dostęp w trybie binarnym (ignoruje znaki specjalne) | 't'  tekst ]
[ '+' - dopisanie | ' ' ]
fp.close() # Zamknięcie pliku (zwolnienie uchwytu)
fp.flush() # Wymuszenie zapisu z cache systemu na dysk
linia = fp.read() # odczyt jednej linii z pliku tekstowego
lista_linii = fp.readlines() #Odczyt aż do końca pliku i umieszczenie w liście
n_znakow = fp.read(n) #Odczyt n znaków do listy
fp.seek(numerznaku) #Ustawienie się w dowolnym miejscu w pliku
fp.tell() #Odczyt miejsca w pliku, w którym jesteśmy
fp.write("abrakadabra") #Zapis ciągu znaków 'abrakadabra' (bez nowej linii)
#Proszę pamiętać o znakach CR, CR/LF, aby zmienić linię
# Poprawny znak końca linii jest zapisany w module os
fp.write(os.linesep) # Przechodzi do nowej linii
Programowanie FizMed, wykład 7 2
Matplotlib - http://matplotlib.sourceforge.net/
Matplotlib jest zbiorem bibliotek i procedur umożliwiającym wykonywanie wykresów i
rysunków w Pythonie. Używany jest także przez Sage.
matplotlib.pylab
(MatLab)
matplotlib.patches
pyplot+numpy
matplotlib.axes
matplotlib.collections
matplotlib.lines
matplotlib.cm
matplotlib
matplotlib.color
matplotlib.figure
matplotlib.ticker
matplotlib.artist
matplotlib.text
matplotlib.image
Programowanie FizMed, wykład 7 3
Matplotlib
Importowanie biblioteki:
import numpy as np # numpy nie jest częścią matplotlib, ale bez
#niego nie da się używać
import matplotlib.pyplot as mpl
Jeżeli nie chcemy za każdym razem odwoływać się poprzez pełną
ścieżkę matplotlib.pyplot lub numpy możemy utworzyć swoją
skróconą nazwę - alias. Tworzymy w ten sposób oddzielną przestrzeń
nazw (namespace) o nazwie mpl dla matplotlib.pyplot i np dla numpy.
Jest to zalecane podejście w przypadku pisania osobnego programu,
tak jak robiliśmy to na zajęciach.
Możemy też skorzystać z modułu pylab, który łączy w sobie obie
przestrzenie nazw: pyplot i numpy.
import pylab as pl
Programowanie FizMed, wykład 7 4
Matplotlib  składniki rysunku
figure i axes
figure - jest centralnym obiektemnależącym do klasy matplotlib.figure.Figure,
który "przechowuje" wykresy lub obrazki (container).
import matplotlib.pyplot as mpl
f1 = mpl.figure()
mpl.show() # wyświetla puste "ramy"
axes - są obiektami klasy matplotlib.axes.Axes, które "przechowują" wykresy lub
obrazki
f1 = mpl.figure()
ax1= f1.add_subplot(121)
ax2 = f1.add_subplot(122)
mpl.show() # wyświetla "ramy" z "osiami"
ax1 ax2
1
2
F.add_subplot(2,2,1)
F.add_subplot(2,2,2)
4 #F.add_subplot(2,2,3) #brak!!
F.add_subplot(2,2,4)
Programowanie FizMed, wykład 7 5
Matplotlib  podstawowe składniki (primitives)
http://matplotlib.sourceforge.net/users/artists.html
Rysunki oraz obiekty na nich umieszczone składają się z mniejszych i
prostszych obiektów (Line2D, Patch, Circle, Rectangle, Text), z których wiele
ma podobne znaczenie (na przykład o.patch zwykle odnosi się do prostokąta
będącego tłem obiektu o).
P1 = o.patch # o może być np. typu figure lub axes
P1.set(facecolor = 'green') # ustawia kolor tła obiektu o na zielony
Wszystkie opcje związane z danym składnikiem rysunku tworzą słownik, do
którego mamy dostęp poprzez metodę
matplotlib.artist.getp(P1)
Figura przechowuje też listy swoich składników.
axes lista obiektów typu Axes
images lista obrazków
legends lista opisów figury (osie mają swoje kolekcje)
lines lista linii należących do figury
patches lista figur geometrycznych na wykresie
texts lista napisów
Podobne listy przechowują też obiekty klasy Axes.
Programowanie FizMed, wykład 7 6
Metody klasy axes
Klasa matplotlib.axes. Axes posiada wiele różnych metod, które służą do
rysowania wykresów, histogramów, obrazków itd.
http://matplotlib.sourceforge.net/gallery.html
http://www.scipy.org/Cookbook/Matplotlib
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
f1 = plt.figure() # tworzymy Figurę f1
ax1= f1.add_subplot(121) # na f1 tworzymy rysunek (axes) ax1
ax1.plot([1,2,3,4],[0,-1,-2,5],'g>')# metoda plot rysuje wykres na podstawie 2
obiektów klasy iterable
ax1.fill([-0.1, 0.1, 0],[-1,-1,1],'r', alpha = 0.4)
# fill rysuje wielokąt (trójkąt) o współrzędnych (-0.1,-1), (0.1,-1), (0,1), kolorze
czerwonym i 40% przezroczystości
#koniec pierwszego wykresu
moj_obr =plt.imread("klocki_lego.jpg") #wczytujemy obrazek jako tablicę 2D
ax2 = f1.add_subplot(122) # tworzymy rysunek (axes) ax2
ax2.imshow(moj_obr) # metoda imshow wyświetla tablicę
plt.show() # finalizuje obrazek
Programowanie FizMed, wykład 7 7
"Dekoracje"
Każdy z tworzonych właśnie wykresów/obrazków możemy opisać
ax1= f1.add_subplot(121)
ax1.set_xlabel("Opis osi x")
ax1.set_title("Tytuł wykresu")
#Lub dopisać dowolny tekst
plt.text(0.1,0.1,"Tu jest tekst w punkcie (0.1, 0.1)") # na rysunku
ax1.annotate("Tekst", (0.5,0.5), xycoords="axes fraction", va="center", ha="center",
bbox=dict(boxstyle="round, pad=1", fc="w")) # na konkretnej osi
Możemy też zmienić kolor tła
Pat = ax1.patch # dostęp do obiektu tła konkretnej osi
Pat.set_facecolor('green')
Możemy dodawać linie
ax1= f1.add_subplot(121)
x = np.arange(0,5,0.1)
ax1.plot(x,2*x)
# Ta instrukcja już tworzy listę linii. Tak więc każdą kolejną musimy dołożyć do naszej
listy instrukcją extend.
#Tworzymy najpierw nową linię L1 i podajemy, że ma być na figurze f1
L1 = matplotlib.lines.Line2D([0, 1], [0, 1], transform=f1.transFigure, figure=f1)
#dodajemy ją do listy linii figury f1 jako element listy
f1.lines.extend( [L1] )
Możemy też dodawać całe figury
rect = matplotlib.patches.Rectangle( (1,1), width=5, height=12)
ax.add_patch(rect)
Programowanie FizMed, wykład 7 8
Matplotlib w sesji interaktywnej i nieinteraktywnej
Sesja interaktywna  po każdej instrukcji możemy odświeżyć rysunek
import matplotlib as mpl
import matplotlib.pyplot as plt
plt.ion() # metoda ion() włącza tryb interaktywny,
# ioff() wyłącza
F = plt.figure()
ax1 = F.add_subplot(111)
plt.draw() # odświeża obrazek, ale nie blokuje konsoli
#itd
Sesja nieinteraktywna  obraz musi zostać przygotowany w całości zanim
zostanie wyświetlony  np w programie.
import matplotlib as mpl
import matplotlib.pyplot as plt
F = plt.figure()
ax1 = F.add_subplot(111)
plt.draw() # nic nie pojawia się
plt.show() # obrazek się pojawia, ale nie można wydać
# nowych poleceń
Programowanie FizMed, wykład 7 9
Skąd biorą się okienka w programie - backends
Grafika wyświetlana przez matplotlib pojawia się w oknie, które tworzone
jest przez manadżera okien (WindowManager) i zależy od środowiska w
jakim pracujemy.
Backend, to biblioteka elementów odpowiedzialna za obsługę i rysowanie
okien.
Standardowo Python obsługuje okna poprzez bibliotekę Tkinter czyli
"backend Tk".
import matplotlib as mpl
mpl.use('TkAgg') # informuje matplotlib, że rysuje używając Tk
import mpl.backends.backend_tkagg
Uwaga, nie musi to być konieczne, jeżeli backend ma poprawnie ustawioną
domyślną wartość!
Domyślny backend możemy sprawdzić poprzez funkcję
mpl.get_backend()
'TkAgg'
Programowanie FizMed, wykład 7 10
Backend  Canvas - Figure
Wcześniej, przy omawianiu matplotlib, powiedziane było, że Figure jest
podstawowym elementem rysunku. Jest to stwierdzenie prawdziwe z
punktu widzenia matplotlib.
W związku z istnieniem różnych backendów konieczne było utworzenie
jeszcze jednego, pośredniego etapu pomiędzy menadżerem okien a
matplotlib tzw. Canvas ("Płótno").
System operacyjny
Menadżer okien
Backend -
Matplotlib -
Canvas
Figure
Programowanie FizMed, wykład 7 11
Backend  Canvas - Figure
Tak więc system operacyjny poprzez menadżera okien, tworzy okno.
Wybrany przez nas backend jest pośrednikiem pomiędzy oknem a
matplotlib poprzez Canvas ("płótno").
Wcześniej, gdy używaliśmu funkcji show() z konsoli Python odbywało
się to automatycznie, przy użyciu domyślnych ustawień.
W przypadku pisania niezależnego programu należy to zrobić
samodzielnie. Aby wyświetlić puste okno potrzebujemy 2 elementy:
Canvas oraz Toolbar, które musimy osadzić na oknie dostarczonym
przez Tkinter.
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.backends.backend_tkagg import NavigationToolbar2TkAgg
FigureCanvasTkAgg
NavigationToolbar2TkAgg
Programowanie FizMed, wykład 7 12
Python 2 czy 3?
Moduł Tkinter, a co za tym idzie backend TkAgg, jest obecny w każdej dystrybucji
Pythona i jest niezależny od modułu matplotlib.
Obecny jest standardowo w Pythonie 2 i 3, z tym, że zmienione zostały nazwy
głównych obiektów oraz modułów.
Można jednak w prosty sposób ominąć ten problem i stworzyć kod, który będzie
działał w obu wersjach Pythona.
Kod na następnym slajdzie:
1/ Załaduje matplotlib z odpowiednim backendem.
2/ Musi to być zrobione przed wczytaniem innych modułów z matplotlib
3/ Sprawdzi, która wersja Pythona go wykonuje.
4/ W zależności od wersji Pythona, załaduje odpowiednie moduły z Tkinter
Na końcu zostanie utworzony przkładowy wykres.
Programowanie FizMed, wykład 7 13
Prosty program z oknem "od zera" - początek
import matplotlib as mpl
mpl.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.backends.backend_tkagg import NavigationToolbar2TkAgg
import matplotlib.pyplot as plt
import sys
if sys.hexversion >= 0x03000000:
inPy3 = True
import tkinter as Tkinter
import tkinter.scrolledtext as ScrolledText
import tkinter.messagebox as tkmb
import tkinter.simpledialog as SimpleDialog
import tkinter.filedialog as FileDialog
else:
inPy3 = False
import Tkinter as Tkinter
import ScrolledText as ScrolledText
import tkMessageBox as tkmb
import tkSimpleDialog as SimpleDialog
import tkFileDialog as FileDialog
Programowanie FizMed, wykład 7 14
Osadzanie matplotlib w Tkinter
Następnie musimy:
1/ Utworzyć okno w menadżerze okien
2/ Utworzyć rysunek (Figure) pyplot
3/ Związać z tym oknem Canvas i NavigationToolbar.
4/ Rozmieścić elementy w oknie
5/ Narysować rysunek w Canvas.
T = Tkinter.Tk() # tworzymy puste okno na bazie Tkinter.Tk()
T.grid() # wybieramy sposób organizacji elementów w oknie
Myfig = plt.figure() # tworzymy Figurę pyplot
Canvas = FigureCanvasTkAgg(Myfig, master=T)
Toolbar = NavigationToolbar2TkAgg(Canvas, T)
Toolbar.update()
Toolbar.grid(column=0,row=0, sticky=Tkinter.W+ Tkinter.N+Tkinter.S)
Canvas._tkcanvas.grid(column=0,row=1, sticky = Tkinter.W+Tkinter.E+
Tkinter.N+ Tkinter.S)
ax1 = Myfig.add_subplot(111)
ax1.plot([1,2,3,4])
Canvas.show()
ax1.clear()
Canvas.show()
Programowanie FizMed, wykład 7 15
#itd
Tkinter = okienka w Pythonie
http://docs.python.org/release/3.1.5/library/tkinter.html
http://fossies.org/dox/Python-3.2.3/namespacetkinter.html
Moduł Tkinter służy do obsługi "okienek" w Pythonie.
Najprostsze z nich to okienka dialogowe, które pozwalają np. podać
liczbę całkowitą, wybrać nazwę pliku do odczytu lub zapisu, zarządać
od użytkownika potwierdzenia jakiejś akcji.
Możemy je zrealizować poprzez 3 główne moduły (nazwy z Python3)
import tkinter.messagebox as MessageBox
import tkinter.simpledialog as SimpleDialog
import tkinter.filedialog as FileDialog
import tkinter.colorchooser as ColorDialog
Jeżeli nie zostało to zrobione wcześniej, utworzenie takiego okienka
powoduje pojawienie się również domyślnego głównego okna.
Najlepiej jest go utworzyć samemu i zaraz schować.
root = tkinter.Tk()
root.withdraw()
Programowanie FizMed, wykład 7 16
tkinter.messagebox
http://docs.python.org/release/3.1.5/library/tkinter.html
import tkinter.messagebox as tkmb #Python 3
import Tkinter.tkMessageBox as tkmb #Python 2
Okna, których wynikiem jest odpowiedz dająca się przedstawić w postaci
"Tak", "Nie" lub "Nie wiem" możemy utworzyć korzystając z następujących
metod. Wartości, które zwracają w zależności od wciśniętego przycisku
znajdują sie po znaku '#'
tkmb.askokcancel("Tytuł okna", "Wiadomość") #OK=True, Cancel=False
tkmb.askretrycancel("Tytuł okna", "Wiadomość") #True, False
tkmb.askyesno("Tytuł okna", "Wiadomość") #True, False
tkmb.askyesnocancel("Tytuł okna", "Wiadomość") #True, False, None
tkmb.askquestion("Tytuł okna", "Wiadomość") # "yes", "no"
Okna, które wymagają tylko prostego potwierdzenia tworzymy poprzez:
tkmb.showerror("Tytuł okna", "Wiadomość")
tkmb.showinfo("Tytuł okna", "Wiadomość")
Przykłady
tkmb.showwarning("Tytuł okna", "Wiadomość")
Programowanie FizMed, wykład 7 17
tkinter.simpledialog
import tkinter.simpledialog as SD #Python 3
import Tkinter.tkSimpleDialog as SD #Python 2
Okna, których wynikiem jest odpowiedz dająca się przedstawić w postaci
liczby lub ciągu znaków tworzymy przy pomocy klasy simpledialog.
Argumenty title i prompt moga wystąpić jako argumenty pozycyjne.
SD.askinterger(title="Tytuł okna", prompt="Wiadomość", initialvalue=
domyślna_wartość_str)
SD.askfloat("Tytuł okna", "Wiadomość", initialvalue= domyślna_wartość_str)
SD.askstring("Tytuł okna", "Wiadomość", initialvalue= domyślna_wartość_str)
Uwaga! Domyślna wartość we wszystkich przypadkach powinna być
konwertowana na typ str, bo taka jest zawartość okna dialogowego.
SD.askfloat("Pytanie", "Podaj liczbę", initialvalue=0.0) # ! nie wyświetli się!
SD.askfloat("Pytanie", "Podaj liczbę", initialvalue=str(0.0)) # OK!
Przykłady
Programowanie FizMed, wykład 7 18
tkinter.filedialog
import tkinter.filedialog as FD #Python 3
import Tkinter.tkFileDialog as FD #Python 2
http://tkinter.unpythonic.net/wiki/tkFileDialog
Okna, których celem jest znalezienie istniejącego pliku, katalogu lub podanie
nazwy pliku do zapisu tworzymy przy pomocy klasy filedialog. Niektóre jej
metody:
#zwraca str z nazwą katalogu
FD.askdirectory(title="Tytuł okna", initialdir="początkowy_katalog")
# zwraca obiekt file ('uchwyt' na plik)
FD.askopenfile(title="Tytuł okna", mode="tryb_otwarcia", initialdir="." )
# zwraca nazwę pliku
FD.askopenfilename(title="Tytuł okna", initialdir= ".")
FD.asksaveasfile(title="Tytuł okna", prompt="Wiadomość", initialvalue=
domyślna_wartość_str)
FD.asksaveasfilename(title="Tytuł okna", prompt="Wiadomość", initialvalue=
domyślna_wartość_str)
Okna typu save lub open moga mieć dodatkową opcję wskazującą na
rozszerzenia plików, których można użyć.
filetypes = lista 2-krotek ("opis", "*.rozszerzenie")
filetypes = [("Word","*.doc"), ("RTF", "*.rtf")]
Przykłady
Programowanie FizMed, wykład 7 19
Widgety Tkinter
Widgety są elementarnymi składnikami okna. Sa nimi np przyciski (Button),
etykiety (Label), pola tekstowe (Text, scrolledtext).
tkinter.Label
lblTmin = tkTkinter.Label(text = str(10.0))
lblTmax = tkTkinter.Label()
lblTmax["text"] = "100.0"
tkinter.Button
QUIT = tkinter.Button(text = "QUIT", fg = "blue", command = _quit)
hi_there = tkinter.Button(text = "Instructions", command = say_hi)
tkinter.Text
mojtext = tkinter.Text(text = "Opis", fg = "blue")
tkinter.scrolledtext
txtInfo = scrolledtext.ScrolledText(wrap="word", width=40, height = 5)
Widgetem jest również obiekt Canvas, na którym możemy umieścić obrazek z
matplotlib
Programowanie FizMed, wykład 7 20
Tkinter.Button
Button(Przycisk) służy do wywołania pewnej akcji (funkcji) po jego naciśnięciu.
QUIT = tkinter.Button(text = "QUIT", fg = "blue", command = _quit)
hi_there = tkinter.Button(text = "Instructions", command = say_hi)
Możemy go zablokować poprzez zmianę stanu na "nieaktywny"
QUIT.config(state = "disabled")
Lub ponownie aktywować
QUIT.config(state = "normal")
Aby przycisk mógł poprawnie działać musimy zdefiniować funkcję, która będzie
wywołana przy jego wciśnięciu, tzw. Callback.
W powyższym przykładzie potrzebujemy dwie funkcje:
def _quit():
print("wychodzę z aplikacji")
quit()
def say_hi():
print("Hi!")
Programowanie FizMed, wykład 7 21
Menadżery geometrii  pack i grid
Menadżery geometrii służą do rozmieszczania widgetów w oknie.
Grid działa podobnie do sposobu tworzenia tabeli w HTML.
Chcemy utworzyć następujące okno - rodzaj kontrolek nie gra roli.
Programowanie FizMed, wykład 7 22
Menadżery geometrii  grid
Pierwszym krokiem jest wirtualne podzielenie tego okna na równe kawałki.
columns = kolumny
el1 el2 el3 el4 el5
el6 el7
el8
el9
el10 el11
Programowanie FizMed, wykład 7 23
rows = rzędy
Menadżery geometrii  grid
Elementy w naszym szkielecie umieszczamy przy pomocy zmiennych
column i row
el1.grid(column=0, row=0, sticky=Tkinter.W+Tkinter.E)
el2.grid(column=1, row=0, sticky=Tkinter.W+Tkinter.E)
el3.grid(column=2, row=0, sticky=Tkinter.W+Tkinter.E)
el4.grid(column=3, row=0, sticky=Tkinter.W+Tkinter.E)
el5.grid(column=4, row=0, sticky=Tkinter.W+Tkinter.E)
el6.grid(column=0, row=1, sticky=Tkinter.W+Tkinter.E)
Elementy, które zajmują więcej miejsca musimy "rozciągnąć"
parametrami colspan i rowspan.
el7.grid(column=1, row=1, colspan = 4, rowspan= 3,
sticky=Tkinter.W+Tkinter.E+Tkinter.S+Tkinter.N)
el11.grid(column=1, row=4, colspan = 4, rowspan= 1,
sticky=Tkinter.W+Tkinter.E+Tkinter.S+Tkinter.N)
Parametr "sticky" określa w jaki sposób kontrolka wypełnia
przeznaczone jej miejsce.
Programowanie FizMed, wykład 7 24
Tkinter w programie
Okienek bazujących na Tkinter możemy używać w sesji interaktywnej jak i w
programie nieinteraktywnym.
W tym drugim przypadku zwykle tworzymy nową klasę, która tworzy nam
okno (o tworzeniu klas już mówiliśmy).
# Tu się zaczyna definicja klasy (jeszcze nie kompletna)
class clsMoja(Tkinter.Tk): # klasa dziedziczy po obiekcie Tk z modułu Tkinter
def __init__(self, parent): # metoda __init__ inicjalizuje okno
Tkinter.Tk.__init__(self, parent) # można przez super.
self.parent=parent
#wybieramy menadżer geometrii
self.grid()
# następnie tworzymy elementy okna
self.hi_there = Tkinter.Button(self,text = "Instructions", command =
self.say_hi)
# Tu się zaczyna główny program
if __name__ == "__main__":
app = clsMoja(None)
app.title('Tytuł aplikacji')
app.mainloop()
Programowanie FizMed, wykład 7 25
Program z jednym przyciskiem
#/usr/bin/python3
import tkinter as Tkinter
# Tu się zaczyna definicja
class clsMoja(Tkinter.Tk):
def __init__(self, parent):
Tkinter.Tk.__init__(self, parent)
self.parent=parent
self.grid()
self.hi_there = Tkinter.Button(self,text = "Mówię hi", command = self.say_hi)
self.hi_there.grid(column=0, row=0,
sticky=Tkinter.E+Tkinter.S+Tkinter.W+Tkinter.N)
def say_hi(self):
Tkinter.messagebox.showinfo("Ważna informacja", "Hi !")
# Tu się zaczyna główny program
if __name__ == "__main__":
app = clsMoja(None)
app.title('Tytuł aplikacji')
app.mainloop()
Programowanie FizMed, wykład 7 26
Koniec na dzisiaj!
Programowanie FizMed, wykład 7 27


Wyszukiwarka