728x90
SMALL
- 오늘은 Jupyter를 이용해 파이썬의 여러 가지 라이브러리(folium, tkinter)를 실습해 보았습니다.
💻 Jupyter Notebook
- 어제 실습했던 공간인 Colab은 구글 서버에서 파이썬이 실행되는 환경입니다.
- 오늘 실습을 진행하는 공간인 Jupyter는 로컬 PC에서 파이썬이 실행되는 환경입니다.
- 이를 실행시키기 위해 Anaconda를 설치했고, Colab 환경에서 진행하지 않는 이유는 추후에 GUI 작업을 위해서입니다.
- 추가적으로 설치된 Spyder는 python의 실제 개발 환경이 이루어지는 공간입니다.
- Jupyter을 실행하고 브라우저의 URL을 살펴보면,
http://localhost:8888/notebooks/myworkspace/
12%EC%9E%A5_(%EC%8B%A4%EC%8A%B5%EC%9A%A9)_folium
.ipynb
- 위와 같이 되어있고, 이 주소의 의미는 다음과 같습니다.
- localhost의 IP는 127.0.0.1로 고정되어있고,
- Port 번호도 8888로 고정되어 있습니다.
- 한글 파일이나 폴더는 이름이 깨져서 들어가기 때문에 윈도우에서는 괜찮으나, 리눅스 환경에서는 위험한 파일명일 수 있습니다.
- 참고로 이 한글 표현은 16진수로 표기됩니다.
✨ 진수법
- 2진수는 0과 1, 10진수는 0~9의 수로 이루어져있고, 16진수는 0~9, A~F의 문자들로 이루어져 있습니다.
- 이 중 16진수는 HardWare에서는 메모리, Web에서는 색상(RGB)을 나타내기 위해 주로 쓰이게 됩니다.
🤓 folium
- folium은 지도 위에 데이터를 시각화하고 표현해주는 파이썬의 지도 시각화 라이브러리입니다.
- 라이브러리를 설치할 때 버전을 꼭 살펴본 뒤, 설치하는 것이 좋은데, 이유는 호환성 측면에서 문제가 생기지 않게 하기 위함입니다.
- 저 같은 경우에도 오늘 실습을 진행하며 folium을 설치할 때, 호환 에러가 발생하였습니다.
- 그래서 진행한 해결 방안은 다음과 같습니다!
- 제 PC에서 환경 변수(PATH)를 다시 설정해준 뒤, 적용을 위해 재부팅 후,
- !pip install folium --force-reinstall 명령어로 다시 folium을 설치하였습니다.
- 그 후에도 folium에 내장되어있는 기존 numpy 라이브러리 버전과도 충돌이 일어나서
- !{sys.executable} -m pip install "numpy<2.1" --force-reinstall 명령어를 통해 numpy를 2.1 버전보다 낮은 버전으로 재설치하였고,
- 다시 folium을 설치해줬더니 정상적으로 돌아가게 되었습니다.
- 아마도 제 python 버전과 folium의 버전의 호환이 정상적으로 이루어지지 않았기에 일어난 문제가 아니었나 싶습니다.
- 이제 본격적인 실습에 들어가봅시다!
✨ folium.Map()
- folium의 Map 함수에 [위도, 경도]를 넣어주고 할당한 변수를 출력하게 되면 좌표에 해당하는 지도를 그려줍니다.
- zoom_start 옵션을 통해서 보여지는 지도의 배율을 미리 정해줄 수도 있고,
- tiles 옵션을 통해서 지도의 테마도 변경해줄 수 있습니다.
Tiles — Folium 0.19.4 documentation
Make this Notebook Trusted to load map: File -> Trust Notebook
python-visualization.github.io
- tiles 옵션과 관련해서는 위 공식 문서를 참고해보시면 될 것 같습니다!
✨ folium.Marker()
maps = folium.Map([lat1, long1],
zoom_start=14,
tiles='OpenStreetMap HOT')
folium.Marker([lat1, long1]).add_to(maps)
folium.Marker([lat2, long2]).add_to(maps)
maps
- Marker 함수에 해당 [위도, 경도] 좌표를 넣어주고, 전에 생성된 maps 변수에 추가해주면 해당 위치에 마커가 표시됩니다.
- 다른 Marker를 추가하려면 Marker를 하나 더 만들어주고 연결해주면 끝!
- tooltip 옵션을 통해 Marker를 사용자가 Hover했을 때 해당 옵션에 들어간 텍스트를 보이게 할 수도 있고,
- icon 옵션을 통해 Marker의 모양을 변경할 수도 있습니다. (예를 들자면, icon=folium.Icon(color='red',icon='star'))
- icon에 설정할 수 있는 색상은 다음과 같습니다.
'red', 'blue', 'green', 'purple', 'orange', 'darkred', 'lightred', 'beige', 'darkblue', 'darkgreen', 'cadetblue', 'darkpurple', 'white', 'pink', 'lightblue', 'lightgreen', 'gray', 'black', 'lightgray'
- icon에 설정할 수 있는 모양은 https://fontawesome.com/v4.7.0/icons에서 확인할 수 있고, 이 페이지에서 보여지는 아이콘을 사용할 때에는 prefix=’fa’ 옵션을 추가해주어야 정상적으로 적용됩니다.
- 최종적으로 보여지는 화면은 다음과 같습니다.
🤓 tkinter
- UI는 사용자 인터페이스(User Interface)로써, 사용자와 코드 사이를 연결하는 모든 것을 의미합니다.
- GUI는 Graphical User Interface의 약자로, UI 중 시각적인 부분을 담당합니다.
- 그렇기 때문에 UI는 GUI를 포함하는 개념입니다. 이 GUI를 맛보기(?) 위해 tkinter 라이브러리를 활용해 실습을 진행해보았습니다.
- 참고로 tkinter는 스마트팩토리 등에서 특정 기기의 패널 UI를 만들 때에 사용되는 라이브러리입니다.
🪟 창 생성
- tkinter는 TK() 함수를 통해 창을 생성하고, mainloop() 함수로 창을 실제 띄우는 작업을 진행합니다.
- 그렇기 때문에 창이 어떻게 구성될 지에 대한 코드는 mainloop() 함수가 호출되기 전에 작성되어야 합니다.
- title() 함수로 창의 제목을 표현할 수 있으며, geometry(’가로x세로’)를 통해 창의 크기를 결정
✨ Label()
- 이 레이블은 위젯이라고도 불리며, IT 업계에서는 컴포넌트라고도 불립니다.
- 띄워진 창에 텍스트를 표기하려면 Label() 함수가 필요한데, 이 Label()의 text 옵션으로 원하는 텍스트를 집어넣을 수가 있습니다.
- 레이블이 설정되었다면, 이 레이블을 pack() 함수로 패킹해주어야 실제로 창에 출력됩니다.
- Label 함수의 옵션은 여러 가지가 존재하는데 목록은 아래와 같습니다.
image = PhotoImage(file='maps.png')
- 텍스트가 아닌 이미지 레이블을 만들기 위해서는
- 먼저 PhotoImage 클래스의 객체를 생성하고, (확장자는 gif, png, pgm, ppm 등)
- 이미지 객체는 바로 보여지지 않기 때문에, 생성 이후 Label() 함수 내에 image 옵션을 해당 객체로 지정해준 뒤, 텍스트와 마찬가지로 반드시 패킹해주어야 합니다.
- 창이 뜨지 않고,
TclError: image "pyimage4" doesn't exist
- 위와 같은 TclError가 발생하면, 커널을 재실행해주시면 해결됩니다.
✨ 위젯 배치
- 여러 개의 위젯을 배치하기 위한 방법은 두 가지가 존재하는데, 바로 절대 위치와 상대 위치입니다.
- place(x=x좌표, y=y좌표) 함수를 통한 절대 위치로 설정도 가능하고,
- grid(), pack() 함수를 이용한 상대 위치로의 설정도 가능합니다.
- 이 중 grid(row=행, column=열) 함수는 격자 한 칸에 위젯을 배치하는 형태이고,
- pack() 함수는 위젯들 간의 상대적 위치로 위젯을 배치하는 형태로 보시면 되겠습니다.
✨ Button()
- 버튼을 생성할 때에도 Label과 같이 안에 들어갈 text와 width, height를 넣어주면 버튼이 생성됩니다.
- 버튼의 command 옵션에 실행하고 싶은 함수를 선언 후 넣어주게 되면, 버튼을 누를 시 해당 함수를 호출할 수도 있습니다.
✨ 동적 변수
- 동적 변수란, 화면이 생성된 후에 변하는 값을 저장하는 변수입니다.
- 문자열 동적 변수는 StringVar(), 정수형은 IntVar(), 실수형은 DoubleVar()로 생성해주시면 됩니다.
- Label 객체에 textvariable 옵션을 통해 동적 변수를 넣어주고, 이 변수의 값을 변경해주기 위해 set() 함수를 선언했던 버튼 함수에 추가해주게 되면, 버튼을 누를 때, 이 동적 변수가 변하게 됩니다!
- 여기까지 진행된 결과물은 다음과 같습니다.
- 추가로 random 라이브러리와 global 변수를 활용해서 구구단 프로그램도 만들어보았습니다.
- 해당 결과물을 만들기 위한 코드는 다음과 같습니다. (제가 임의로 수업에서 제공해주신 코드를 수정해보았습니다.)
import random
from tkinter import *
def make_question():
global num1, num2
num1 = random.randint(2, 9)
num2 = random.randint(1, 9)
question.set(f"{num1} x {num2} ?")
answer.set("")
def check_answer():
user_answer = answer.get()
if user_answer.isdigit() and int(user_answer) == num1 * num2:
messagebox.showinfo("정답 확인", "정답입니다!")
make_question()
else:
messagebox.showerror("정답 확인", f"틀렸습니다! 정답은 {num1 * num2} 입니다.")
answer.set("")
num1, num2 = 0, 0
main = Tk()
main.title('구구단')
main.geometry('295x230')
question = StringVar()
answer = StringVar()
title_label = Label(main, text="구구단을 외자!", font=('Malgun Gothic', 18), fg='DodgerBlue3')
title_label.grid(row=0, column=0, columnspan=2, pady=(10, 0))
question_label = Label(main, textvariable=question, font=('Malgun Gothic', 24), fg='black')
question_label.grid(row=1, column=0, columnspan=2)
answer_entry = Entry(main, textvariable=answer, font=('Malgun Gothic', 18), justify='center')
answer_entry.grid(row=2, column=0, columnspan=2, pady=10)
new_question_button = Button(main, text="새로운 문제", font=('Malgun Gothic', 14), bg='SteelBlue3', command=make_question)
new_question_button.grid(row=3, column=0, padx=20, pady=10, sticky='e')
check_answer_button = Button(main, text="정답 확인", font=('Malgun Gothic', 14), bg='SpringGreen4', command=check_answer)
check_answer_button.grid(row=3, column=1, padx=20, pady=10, sticky='w')
make_question()
main.mainloop()
- 여기에는 곧 작성할 Entry도 포함되어 있습니다. 아래에 추가로 설명하겠습니다.
✨ Entry()
- Entry(엔트리)는 화면에서 입력받을 수 있는 칸을 의미합니다.
- Entry에 입력된 값을 받아오기 위해 get() 함수를 사용하셔서 선언된 함수에 집어넣고 버튼의 command 옵션에 추가하게 되면 사용자의 입력 값을 받아올 수 있게 됩니다.
✨ Frame
- 프레임을 통해 생성된 tkinter 창 내에서도 영역을 구분해서 나타낼 수 있습니다.
- 프레임이 있어도 내부 위젯이 없다면 화면에 나타나지 않게 됩니다.
- 프레임에 borderwidth 옵션을 통해 테두리를 나타낼 수 있는데, 이 테두리는 relief 옵션이 없다면 보여지지 않게 됩니다. 따라서 relief='groove'와 같이 꼭 지정해주셔야 합니다!
- 위에서 배운 모든 내용을 가지고 최종적으로 어제 진행했었던 핫플레이스 분석을 tkinter 창 내에서 할 수 있게 되었습니다.
🤔 4일차 회고
- 오늘은 GUI 실습을 위해 Colab 환경이 아닌 Jupyter 환경에서 수업을 진행했습니다.
- 오늘 tkinter나 folium 라이브러리를 배우며 제가 전공 수업 때 다뤄보지 못한 내용들이 많았기에 이를 통해 위치 관련 서비스나 데이터 분석 툴을 제작해보면 좋겠다는 생각을 하게 되었습니다.
- 그리고 확실히 에러 핸들링과 관련하여 대비를 많이 해야겠다는 생각을 하게 된 것이 실무에 가서는 어떤 에러던지 간에 바로 해결할 수 있는 능력을 요구할 것 같았습니다. 교육을 열심히 들으며 이 문제 해결 능력을 끊임없이 발전시켜 나가야겠습니다.
- 다음 주는 설날 주간이라 수업이 없고, 그 다음 주부터 본격적으로 Python 이론 강의를 나갈 예정입니다.
- 그래서 다음 주 긴 연휴가 예정되어 있는 만큼, ADsP 자격증 공부를 진행하여 추후(02/22 토)에 예정되어 있는 시험을 응시해보려고 합니다!
728x90
LIST
'부트캠프 > LG U+' 카테고리의 다른 글
🤔 함수와 모듈 그리고 클래스 (15) | 2025.02.04 |
---|---|
🤔 Python Programming Basics (w. Spyder) (2) | 2025.02.03 |
🤔 Python과 데이터 분석의 기초 (4) | 2025.01.23 |
🤔 보안 그룹과 EBS 그리고 ELB (10) | 2025.01.22 |
🤔 클라우드와 AWS 그리고 EC2 (2) | 2025.01.21 |