{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":17907,"databundleVersionId":878092,"isSourceIdPinned":false,"sourceType":"competition"},{"sourceId":1425353,"sourceType":"datasetVersion","datasetId":834595}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"\"\"\"시스템에 설치된 폰트 목록을 보고 싶을 때?\"\"\"\n\nimport matplotlib as mpl\nimport matplotlib.pyplot as plt\nimport matplotlib.font_manager as fm\n\n# 시스템에 설치된 폰트 목록 가져오기\n# 리스트의 각 FontEntry 객체에서 폰트 이름(f.name)과 폰트 파일 경로(f.fname)를 튜플로 추출\n# set으로 중복 제거\nfont_info = sorted(set((f.name, f.fname) for f in fm.fontManager.ttflist))\n\n# 이전 폰트 이름 저장 변수\nprev_name = None\n\nprint(\"설치된 폰트 목록\")\n\nfor name, path in font_info:\n    # 폰트 이름이 바뀔 때만 줄 바꿈\n    if name != prev_name:\n        print(f\"\\n📂{name}\")  # 새로운 폰트 이름 출력\n        prev_name = name  # 이전 폰트 이름 업데이트\n    \n    print(f\" - {path}\")  # 해당 폰트의 파일 경로 출력\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T11:32:59.809733Z","iopub.execute_input":"2025-03-19T11:32:59.810089Z","iopub.status.idle":"2025-03-19T11:32:59.827420Z","shell.execute_reply.started":"2025-03-19T11:32:59.810057Z","shell.execute_reply":"2025-03-19T11:32:59.823924Z"},"scrolled":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!apt-get update -qq && apt-get install -qq -y fonts-nanum\n\nfrom IPython.display import set_matplotlib_formats\nset_matplotlib_formats('retina')\n\nimport matplotlib as mpl\nimport matplotlib.pyplot as plt\nimport matplotlib.font_manager as fm\nimport seaborn as sns\n\n%matplotlib inline\n%config InlineBackend.figure_format = 'retina'\n\n# 나눔고딕 폰트 경로\nregular_font_path = \"/usr/share/fonts/truetype/nanum/NanumGothic.ttf\"\nbold_font_path = \"/usr/share/fonts/truetype/nanum/NanumGothicBold.ttf\"\n\n# 폰트 등록 (Matplotlib 내부 폰트 캐시에 추가)\nfm.fontManager.addfont(regular_font_path)\nfm.fontManager.addfont(bold_font_path)\n\n# 기본 폰트 설정\nmpl.rcParams['font.family'] = 'NanumGothic'  # 기본 폰트 지정\nmpl.rcParams['axes.unicode_minus'] = False\n\n# 🔥 자동 Bold 적용을 위해 font weight 매핑\nmpl.rcParams['font.weight'] = 'regular'\nmpl.rcParams['axes.titleweight'] = 'bold'  # 제목은 기본적으로 bold\nmpl.rcParams['axes.labelweight'] = 'bold'  # 축 라벨도 bold\n\n\n########################################################################\n# 테스트\n#######################################################################\n\nplt.figure(figsize=(10, 2))\nplt.text(0.5, 0.6, \"기본체 (Regular)\", fontsize=12, weight='regular', ha='center', va='center')\nplt.text(0.5, 0.4, \"굵은체 (Bold)\", fontsize=12, weight='bold', ha='center', va='center')\nplt.title(\"제목 (Bold 적용 확인)\", fontsize=18, pad=10)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T11:49:51.328703Z","iopub.execute_input":"2025-03-19T11:49:51.329064Z","iopub.status.idle":"2025-03-19T11:49:58.060951Z","shell.execute_reply.started":"2025-03-19T11:49:51.329034Z","shell.execute_reply":"2025-03-19T11:49:58.059726Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"################################################################################################\n######################### Pandas DataFrame Korean Font Update ##################################\n\nimport pandas as pd\nfrom IPython.core.display import display, HTML\n\npd.set_option('display.max_columns', None)  # 모든 열 표시\npd.set_option('display.unicode.east_asian_width', True)  # 한글 정렬 깨짐 방지\n\ndisplay(HTML(\"\"\"\n    <style>\n        @import url('https://fonts.googleapis.com/css2?family=Nanum+Gothic&display=swap');\n        table { font-family: 'Nanum Gothic', sans-serif !important; }\n    </style>\n\"\"\"))\n\n# 테스트\ndf = pd.DataFrame({\n    \"이름\": [\"김철수\", \"이영희\", \"박지민\"],\n    \"나이\": [25, 30, 22],\n    \"도시\": [\"서울\", \"부산\", \"대구\"]\n})\n\ndisplay(df)\n\n################################################################################################\n######################## Plotly Korean Font Update #############################################\n\nimport plotly.graph_objects as go\nimport plotly.io as pio\n\n# Plotly 기본 폰트 설정 (전역 설정)\n# weight = bold or normal\n\npio.templates[\"plotly\"].layout.font.family = \"NanumGothic\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T11:46:51.161762Z","iopub.execute_input":"2025-03-19T11:46:51.162082Z","iopub.status.idle":"2025-03-19T11:46:51.176823Z","shell.execute_reply.started":"2025-03-19T11:46:51.162057Z","shell.execute_reply":"2025-03-19T11:46:51.175872Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Remote Sensing Techniques\n \nRemote sensing utilizes satellite and/or  airborne based sensors to collect information about a given object or area. Remote sensing data collection methods can be passive or active.Passive sensors(e.g., spetral imagers) detect natural radition that is emitted or reflected by the object or area being observed. In active remote sensing energy is emitted and resultant signal that is reflected back is measured.\n![](http://th.bing.com/th/id/OIP.cr73jDfOvCNKcH3-1jcSXgHaFj?w=223&h=180&c=7&o=5&dpr=2.5&pid=1.7)","metadata":{}},{"cell_type":"code","source":"#################### 데이터셋 폴더 및 파일에 대한 요약 정보 ##############################\n\nimport os\n\nroot_dir = \"/kaggle/input\"\n\nfor dirname, dirnames, filenames in os.walk(root_dir):\n    if filenames:  # 파일이 있는 폴더만 출력\n        \n        print(f\"\\n📂 {dirname}\")  # 현재 디렉토리 출력\n        \n        file_count = len(filenames)  # 현재 폴더 내 파일 개수\n        display_count = min(file_count, 5)  # 최대 5개까지만 표시            \n\n        # 파일 목록에서 최대 5개까지만 표시하고, 5개 미만인 경우 그것들만 표시\n        # enumerate에서 i는 인덱스 번호이고, 함수 안에 들어가는 것은 변수명(칼럼)\n        for i, filename in enumerate(filenames[:display_count]):\n            if i == display_count - 1 and file_count <= 5:  \n                print(f\"  └── {filename}\\n\\n\")  # 마지막 파일 (5개 이하인 경우)\n            else:\n                print(f\"  ├── {filename}\")  # 일반 파일 출력\n        \n        if file_count > 5:\n            print(f\"  └── ... (총 {file_count}개 파일)\")  # 5개 초과 시 요약 출력\n        ","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-03-19T10:35:11.245928Z","iopub.execute_input":"2025-03-19T10:35:11.246273Z","iopub.status.idle":"2025-03-19T10:35:17.825527Z","shell.execute_reply.started":"2025-03-19T10:35:11.246241Z","shell.execute_reply":"2025-03-19T10:35:17.824537Z"},"scrolled":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Earth science data & analysis\n\nThe following datasets have been provided as a starter kit to get started with the competition.\n\n1.**Sentinel-5P Carbon Monoxide**\nConcentrations of Carbon monoxide(CO) and water vapor. CO is an important atmospheric trace gas for our understanding of tropospheric chemistry. Main sources of CO are combustion of fossil fuels,biomass burning, and atmospheric oxidation of methane and other hydrocarbons.\n\nSentinel-5 Percursor is statelite launched on 13 october by the European Space Agency to monitor air pollution.The onboard sensor is frequently referred to as Tropomi.\n\n2**Sentinel-5P Nitrogen Dioxide**\nTroposheric and Stratospheric nitrogen dioxide concentration. Nitrogen dioxide enters the atmosphere as a result of anthropogenic activities such as fossil fuel combustion and biomass burning as well as natural processes including microbiological processes in soils,wildfires and lighting.\n\nSentinel-5 Precursor is a satellite launched on 13 october 2017 by the European Space Ageny to monitor air pollution.The onboard sensor is frequently referred to as Tropomi.\n","metadata":{}},{"cell_type":"markdown","source":"**Importing  necessary libraries**","metadata":{}},{"cell_type":"code","source":"# 기본,시각화\n\nimport warnings\nwarnings.filterwarnings('ignore')\n\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n%matplotlib inline\nimport seaborn as sns\nimport plotly.express as px\n\n# 컬러 팔레트\ncnf, dth, rec, act = '#393e46', '#ff2e63', '#21bf73', '#fe9801'\n\n# 지도 시각화 라이브러리 folium\n\"\"\"\n지도의 생성 및 표시 (folium.Map)\n마커 추가 (folium.Marker, folium.CircleMarker)\n폴리곤, 라인 추가 (folium.Polygon, folium.PolyLine)\n히트맵 시각화 (folium.plugins.HeatMap)\nGeoJSON 데이터 활용 가능 (folium.GeoJson)\n\"\"\"\nimport folium \nfrom folium import plugins\n\n# rasterio: 위성 이미지 및 지리공간 래스터 데이터를 처리\n# 공간 데이터를 읽고, 쓰고, 분석하는 데 사용\n!pip install rasterio\nimport rasterio as rio\n\n# 날짜 데이터 처리\nimport datetime as dt\nfrom datetime import datetime","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true,"execution":{"iopub.status.busy":"2025-03-19T10:35:17.826739Z","iopub.execute_input":"2025-03-19T10:35:17.827040Z","iopub.status.idle":"2025-03-19T10:35:29.422797Z","shell.execute_reply.started":"2025-03-19T10:35:17.827000Z","shell.execute_reply":"2025-03-19T10:35:29.421592Z"},"scrolled":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Global Power Plant Database (GPPD)\n\nThe Global Power Plant Database is a comprehensive, open source database of power plants around the world.It centralizes power plant data to make it easier to navigate,compare and draw insights. Each power plant is geolocated and entries contain information on plant capcity, generation,ownership and fueltype. ","metadata":{}},{"cell_type":"code","source":"power_plant = pd.read_csv('/kaggle/input/ds4g-environmental-insights-explorer/eie_data/gppd/gppd_120_pr.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T10:35:29.425227Z","iopub.execute_input":"2025-03-19T10:35:29.426088Z","iopub.status.idle":"2025-03-19T10:35:29.452700Z","shell.execute_reply.started":"2025-03-19T10:35:29.426044Z","shell.execute_reply":"2025-03-19T10:35:29.451787Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"display(power_plant.shape)\n\npp_columns = (power_plant.columns.to_list())\npp_columns = \", \".join(pp_columns)\ndisplay(pp_columns)\n\ndisplay(power_plant.info())\n\ndisplay(power_plant.describe(include=\"all\"))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T10:35:29.454256Z","iopub.execute_input":"2025-03-19T10:35:29.454630Z","iopub.status.idle":"2025-03-19T10:35:29.572516Z","shell.execute_reply.started":"2025-03-19T10:35:29.454601Z","shell.execute_reply":"2025-03-19T10:35:29.571333Z"},"scrolled":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"display(power_plant)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T10:35:29.573645Z","iopub.execute_input":"2025-03-19T10:35:29.573959Z","iopub.status.idle":"2025-03-19T10:35:29.617060Z","shell.execute_reply.started":"2025-03-19T10:35:29.573921Z","shell.execute_reply":"2025-03-19T10:35:29.615926Z"},"scrolled":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"display(power_plant['system:index'])\n\nunique_counts = power_plant.nunique().reset_index()\nunique_counts.columns = ['Column', 'Unique Values']\n\ndisplay(unique_counts)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T10:35:29.618151Z","iopub.execute_input":"2025-03-19T10:35:29.618531Z","iopub.status.idle":"2025-03-19T10:35:29.641124Z","shell.execute_reply.started":"2025-03-19T10:35:29.618489Z","shell.execute_reply":"2025-03-19T10:35:29.640201Z"},"scrolled":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"power_plant.set_index('system:index',inplace=True)\npower_plant","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T10:35:29.642182Z","iopub.execute_input":"2025-03-19T10:35:29.642583Z","iopub.status.idle":"2025-03-19T10:35:29.689687Z","shell.execute_reply.started":"2025-03-19T10:35:29.642542Z","shell.execute_reply":"2025-03-19T10:35:29.688621Z"},"scrolled":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### 시스템/인덱스 칼럼이 데이터 프레임의 인덱스로 설정되었음. 앞에서 구한 칼럼 목록(리스트)를 보며 이것이 각각 무엇을 의미하는지 살펴 보자.\n\ncapacity_mw, commissioning_year, country, country_long, estimated_generation_gwh, generation_gwh_2013, generation_gwh_2014, generation_gwh_2015, generation_gwh_2016, generation_gwh_2017, geolocation_source, gppd_idnr, name, other_fuel1, other_fuel2, other_fuel3, owner, primary_fuel, source, url, wepp_id, year_of_capacity_data, .geo\n\n* **capcity_mw**- electrical generating capcity in megawatts\n  \n* **commissioning year** - year of plant operation \n\n* **country_long**- full name of country\n\n* **estimated_generation_gwh** - estimated annual electricity generation in gigawatt-hours\n  \n* **generation_gwh_2013**- generation of electricity in gigawatt-hours for the year2013\n* **generation_gwh_2014** - generation of electricity in gigawatt-hours for the year2014\n* **generation_gwh_2015** - generation of electricity in gigawatt-hours for the year2015\n* **generation_gwh_2016** - generation of electricity in gigawatt-hours for the year2016\n* **generation_gwh_2017** - generation of electricity in gigawatt-hours for the year2017\n\n* **geolocation_source** - Dataset provider\n\n* **gppd_idnr**- It is id of Global Power Plant Database under department of lllinois Natural Resourcessource\n\n* **name**- name or title of powerplant\n\n* **primary_fuel**-energy source used in primary eletricity generation \n* **other_fuel1** - 에너지 소스 (OTher1)\n* **other_fuel2** - 에너지 소스 (OTher2)\n* **other_fuel3** - 에너지 소스 (OTher3)\n\n* **url** - 에너지원 사이트\n\n* **.geo** - 좌표 (주소)\n\n* **wepp_id**- a reference to a unique plant identifier in the widely used PLATTS-WEPP database\n\n* **year_of_capcity_data**-year the capcity information was reported\n\n* **source**- entity reporting the data\n\n* **owner**- majority shareholder of the powerplant\n","metadata":{}},{"cell_type":"code","source":"for col in power_plant.columns:\n    display(f\"Unique value counts for: {col}\")\n    display(power_plant[col].value_counts())\n    print(\"\\n\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T10:35:29.692584Z","iopub.execute_input":"2025-03-19T10:35:29.692900Z","iopub.status.idle":"2025-03-19T10:35:29.828347Z","shell.execute_reply.started":"2025-03-19T10:35:29.692874Z","shell.execute_reply":"2025-03-19T10:35:29.827316Z"},"scrolled":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"power_plant['name'].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T10:35:29.830795Z","iopub.execute_input":"2025-03-19T10:35:29.831106Z","iopub.status.idle":"2025-03-19T10:35:29.838815Z","shell.execute_reply.started":"2025-03-19T10:35:29.831078Z","shell.execute_reply":"2025-03-19T10:35:29.837671Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### **ax.patches의 기능?**\n\n`plt.figure(figsize=(8,5))`    \n`ax = sns.countplot(x=[\"A\", \"B\", \"C\", \"A\", \"B\", \"C\", \"C\", \"C\"])  # 간단한 예제 데이터 사용`\n\n#### **ax.patches 출력**\n`for p in ax.patches:`     \n`   print(p)`      \n\n#### **출력 예시**\n\n```python\nRectangle(xy=(-0.4, 0), width=0.8, height=2, angle=0)\nRectangle(xy=(0.6, 0), width=0.8, height=2, angle=0)\nRectangle(xy=(1.6, 0), width=0.8, height=4, angle=0)\n```","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(10,6))  \nax = sns.countplot(x=\"primary_fuel\", data=power_plant)  \n\n# 각 막대 높이(카운트 값) 가져오기\nheights = [p.get_height() for p in ax.patches]\n\n# 최솟값 & 최댓값 계산\nymin, ymax = min(heights), max(heights)\n\n# 최솟값 라인 (빨간 점선)\nax.axhline(y=ymin, color='red', linestyle='dashed', linewidth=1, label=f'Min: {ymin}')\n\n# 최댓값 라인 (파란 점선)\nax.axhline(y=ymax, color='blue', linestyle='dashed', linewidth=1, label=f'Max: {ymax}')\n\n# 막대 위에 값 표시 (더 간단한 방법)\nfor p in ax.patches:\n    plt.text(p.get_x() + p.get_width() / 2,  # x 위치\n             p.get_height()+0.2,  # y 위치 (막대 높이)\n             int(p.get_height()),  # 표시할 값\n             ha='center', va='bottom', fontsize=12)  # 가운데 정렬, 폰트 크기 설정\n\nplt.title(\"Count of Primary Fuel Types\", pad=10, weight='medium', fontsize=15)\nplt.xlabel(\"Primary Fuel\", labelpad=10)\nplt.ylabel(\"Count\", labelpad=10)\nplt.xticks(rotation=0)  # x축 레이블 회전 (필요하면 조정)\n\nax.set_ylim(0, ax.get_ylim()[1] * 1.2)\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T10:35:29.840077Z","iopub.execute_input":"2025-03-19T10:35:29.840486Z","iopub.status.idle":"2025-03-19T10:35:30.159918Z","shell.execute_reply.started":"2025-03-19T10:35:29.840447Z","shell.execute_reply":"2025-03-19T10:35:30.158884Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 내림차순 정렬\n\nplt.figure(figsize=(10,6))\n\n# primary_fuel별 개수를 계산하고 내림차순 정렬\nfuel_counts = power_plant[\"primary_fuel\"].value_counts().sort_values(ascending=False)\n\n# 막대 그래프 생성\nax = sns.countplot(x=\"primary_fuel\", data=power_plant, order=fuel_counts.index)\n\n# 최솟값 & 최댓값 계산\nymin, ymax = fuel_counts.min(), fuel_counts.max()\n\n# 최솟값 & 최댓값 라인 추가\nax.axhline(ymin, color='red', linestyle='dashed', linewidth=1, label=f'Min: {ymin}')\nax.axhline(ymax, color='blue', linestyle='dashed', linewidth=1, label=f'Max: {ymax}')\n\n# 막대 위에 값 표시\nfor p in ax.patches:\n    ax.text(p.get_x() + p.get_width()/2, p.get_height() + 0.2, int(p.get_height()), \n            ha='center', va='bottom', fontsize=12)\n\nplt.title(\"Count of Primary Fuel Types\", pad=10, weight='medium', fontsize=15)\nplt.xlabel(\"Primary Fuel\", labelpad=10)\nplt.ylabel(\"Count\", labelpad=10)\nplt.xticks(rotation=0)\nax.set_ylim(0, ymax * 1.2)\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T10:35:30.161065Z","iopub.execute_input":"2025-03-19T10:35:30.161458Z","iopub.status.idle":"2025-03-19T10:35:30.378473Z","shell.execute_reply.started":"2025-03-19T10:35:30.161422Z","shell.execute_reply":"2025-03-19T10:35:30.377480Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 색깔 기준으로 분류\n\nimport matplotlib.cm as cm\n\n# Stock Holder의 기여도 계산 (오름차순 정렬)\nstock_holder_counts = power_plant['owner'].value_counts(ascending=True)\n\nplt.figure(figsize=(10,6))\n\n# 컬러맵 적용 (예: 'viridis', 'Blues', 'coolwarm' 등 선택 가능)\ncolors = cm.Blues(stock_holder_counts.rank(pct=True))  # 순위 기반으로 색상 설정\n\nax = stock_holder_counts.plot(kind='barh', color=colors)\n\n# 막대 위에 숫자 표기\nfor p in ax.patches:\n    ax.text(p.get_width() + 0.5, p.get_y() + p.get_height()/2, int(p.get_width()), \n            ha='left', va='center', fontsize=10)\n\nplt.title('Contribution of Stock Holders', pad=10, weight='medium', fontsize=15)\nplt.xlabel(\"Count\")\n\n# 그래프 너비 조정\nax.set_xlim(0, ax.get_xlim()[1] * 1.05)\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T10:35:30.379380Z","iopub.execute_input":"2025-03-19T10:35:30.379681Z","iopub.status.idle":"2025-03-19T10:35:30.683245Z","shell.execute_reply.started":"2025-03-19T10:35:30.379656Z","shell.execute_reply":"2025-03-19T10:35:30.682169Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\"\"\"\n트리맵 시각화 분석:\n\n1. 비율(%)을 시각적으로 비교하고 싶을 때\n발전량(estimated_generation_gwh)과 용량(capacity_mw) 중 어느 항목이 더 큰 기여도를 가지는지 쉽게 확인 가능.\n\n2. 계층적 데이터를 표현하고 싶을 때\n예: 회사 내 부서별 직원 수, 제품군별 매출, 국가별 GDP 등\n\n3. 다른 그래프(막대그래프, 파이차트)보다 더 직관적인 시각화를 원할 때\n트리맵은 막대그래프보다 면적을 통해 크기를 비교할 수 있어 시각적으로 더 명확함.\n\n\npower_plant 데이터에서 연도별(commissioning_year) 발전량(estimated_generation_gwh)과 용량(capacity_mw)의 총합을 계산함\ngroupby('commissioning_year')을 사용하여 연도별 그룹화하고 sum()을 사용하여 같은 연도에 속한 발전소들의 값을 합산\n\"\"\"\n\n# 그룹화 및 데이터 변환\ntemp = power_plant.groupby('commissioning_year')[['estimated_generation_gwh', 'capacity_mw']].sum().reset_index()\ntemp = temp[temp['commissioning_year'] == max(temp['commissioning_year'])].reset_index(drop=True)\n\n\n# 데이터 변환 (melt)\n# commissioning_year                variable   value 로 정리됨\n\"\"\"\nmelt()란? 트리맵을 만들 때 데이터 가공시 사용함\nWide Format → Long Format으로 변환하는 함수\n즉, 열(column)을 행(row)으로 바꿔주는 역할\n\npath=[\"variable\"]: 트리맵에서 그룹을 구분할 기준 (여기서는 estimated_generation_gwh vs capacity_mw).\nvalues=\"value\": 트리맵 블록 크기를 결정할 값\n\"\"\"\ntm = temp.melt(id_vars=\"commissioning_year\", value_vars=[\"estimated_generation_gwh\", \"capacity_mw\"])\n\n# 컬러 변수 정의 (기본값 설정)\nact, rec = \"blue\", \"red\"\n\n# 트리맵 생성\nfig = px.treemap(tm, path=[\"commissioning_year\", \"variable\"], values=\"value\", height=225, width=1200,\n                 color_discrete_sequence=[act, rec])\n\nfig.data[0].textinfo = 'label+text+value'\nfig.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T10:35:30.684199Z","iopub.execute_input":"2025-03-19T10:35:30.684523Z","iopub.status.idle":"2025-03-19T10:35:32.911952Z","shell.execute_reply.started":"2025-03-19T10:35:30.684496Z","shell.execute_reply":"2025-03-19T10:35:32.910931Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 그룹화 및 데이터 변환\ntemp = power_plant.groupby('commissioning_year')[['estimated_generation_gwh', 'capacity_mw']].sum().reset_index()\n\n# commissioning_year가 0인 데이터 제거\ntemp = temp[temp['commissioning_year'] > 0]\n\n# 20세기(1900~1999) 데이터 필터링\ntemp_20th = temp[temp['commissioning_year'] < 2000]\n\n# 21세기(2000~현재) 데이터 필터링\ntemp_21st = temp[temp['commissioning_year'] >= 2000]\n\n# 데이터 변환 (melt)\ntm_20th = temp_20th.melt(id_vars=\"commissioning_year\", value_vars=[\"estimated_generation_gwh\", \"capacity_mw\"])\ntm_21st = temp_21st.melt(id_vars=\"commissioning_year\", value_vars=[\"estimated_generation_gwh\", \"capacity_mw\"])\n\n# 컬러 변수 정의 (부드러운 색상)\npastel_colors = [\"#A1D6E2\", \"#FFDDC1\"]  \n\n# 2000년대 이전\nfig_20th = px.treemap(tm_20th, path=[\"commissioning_year\", \"variable\"], values=\"value\", height=600, width=1100,\n                       title=\"1900~1999 발전량 및 용량\", color_discrete_sequence=pastel_colors)\n\n# 2000년대 후후\nfig_21st = px.treemap(tm_21st, path=[\"commissioning_year\", \"variable\"], values=\"value\", height=600, width=1100,\n                       title=\"2000년 이후 발전량 및 용량\", color_discrete_sequence=pastel_colors)\n\n# 트리맵 출력 (각각 다른 화면에서 출력)\nfig_20th.show()\nfig_21st.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T10:35:32.912886Z","iopub.execute_input":"2025-03-19T10:35:32.913137Z","iopub.status.idle":"2025-03-19T10:35:33.061307Z","shell.execute_reply.started":"2025-03-19T10:35:32.913115Z","shell.execute_reply":"2025-03-19T10:35:33.060301Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 그룹화 및 데이터 변환\ntemp = power_plant.groupby('commissioning_year')[['estimated_generation_gwh', 'capacity_mw']].sum().reset_index()\n\n# commissioning_year가 0인 데이터 제거\ntemp = temp[temp['commissioning_year']>0]\n\ndisplay(temp)\n\n# 상관행렬 히트맵 시각화\ncorrelation_matrix = temp.corr()\nplt.figure(figsize=(8, 6))\nsns.heatmap(correlation_matrix, annot=True, cmap='Blues', fmt=\".2f\", linewidths=0.5)\nplt.title('Correlation Matrix of Power Plant Data')\nplt.show()\n\n# 산점도 시각화 (연도 vs 발전량, 연도 vs 설비 용량, 설비 용량 vs 발전량)\nfig, axes = plt.subplots(1, 3, figsize=(18, 5))\n\n# 연도 vs 발전량\nsns.scatterplot(data=temp, x='commissioning_year', y='estimated_generation_gwh', ax=axes[0])\naxes[0].set_title('Commissioning Year vs. Estimated Generation (GWh)', pad=15)\n\n# 연도 vs 설비 용량\nsns.scatterplot(data=temp, x='commissioning_year', y='capacity_mw', ax=axes[1])\naxes[1].set_title('Commissioning Year vs. Capacity (MW)', pad=15)\n\n# 설비 용량 vs 발전량\nsns.scatterplot(data=temp, x='capacity_mw', y='estimated_generation_gwh', ax=axes[2])\naxes[2].set_title('Capacity (MW) vs. Estimated Generation (GWh)', pad=15)\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T12:15:15.604267Z","iopub.execute_input":"2025-03-19T12:15:15.604626Z","iopub.status.idle":"2025-03-19T12:15:16.664051Z","shell.execute_reply.started":"2025-03-19T12:15:15.604595Z","shell.execute_reply":"2025-03-19T12:15:16.662905Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Estimated generation growth from commissioning year\ntemp=power_plant.groupby('commissioning_year')[['estimated_generation_gwh','capacity_mw']].sum().reset_index()\ntemp = temp[temp['commissioning_year']!=0]\ntemp=temp.melt(id_vars=\"commissioning_year\",value_vars=[\"estimated_generation_gwh\",\"capacity_mw\"],var_name='Year',value_name='Count')\n\ndisplay(temp.head())\n\nfig=px.area(temp,x='commissioning_year',y='Count',color='Year',height=600,title='Production over time',color_discrete_sequence=[rec,dth])\nfig.update_layout(xaxis_rangeslider_visible=True)\nfig.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T12:18:35.088020Z","iopub.execute_input":"2025-03-19T12:18:35.088327Z","iopub.status.idle":"2025-03-19T12:18:35.161872Z","shell.execute_reply.started":"2025-03-19T12:18:35.088302Z","shell.execute_reply":"2025-03-19T12:18:35.160997Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"full_grouped = power_plant.groupby(['source', 'primary_fuel'])[['capacity_mw', 'estimated_generation_gwh']].sum().reset_index()\ndisplay(full_grouped)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T12:19:33.847845Z","iopub.execute_input":"2025-03-19T12:19:33.848171Z","iopub.status.idle":"2025-03-19T12:19:33.867537Z","shell.execute_reply.started":"2025-03-19T12:19:33.848145Z","shell.execute_reply":"2025-03-19T12:19:33.866479Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"temp_1 = full_grouped.sort_values(by='estimated_generation_gwh',ascending=False)\ndisplay(temp_1)\n\n# 순서 정렬 후 인덱스가 꼬임. 그래서 인덱스를 리셋하고, 기존값을 제거함\n# drop 옵션을 넣지 않을 경우 기존 인덱스는 그대로 유지되면서 (df 항목으로 추가) 새로운 정렬 인덱스가 추가됨\ntemp_1 = temp_1.reset_index(drop=True)\ndisplay(temp_1)\n\n#수치형 자료에만 적용됨\ntemp_1.style.background_gradient(cmap='Blues')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T12:23:04.451195Z","iopub.execute_input":"2025-03-19T12:23:04.451577Z","iopub.status.idle":"2025-03-19T12:23:04.490648Z","shell.execute_reply.started":"2025-03-19T12:23:04.451545Z","shell.execute_reply":"2025-03-19T12:23:04.489589Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 연료별로 소스의 발전 용량을 확인\nfig = px.treemap(full_grouped, \n                 path=['primary_fuel', 'source'],  # 계층 구조: 연료 -> 소스\n                 values='capacity_mw',  # 트리맵의 크기: 발전 용량\n                 color='capacity_mw',  # 색상: 발전 용량 크기\n                 hover_data=['capacity_mw', 'estimated_generation_gwh'],  # 호버 시 추가 정보\n                 color_continuous_scale='Viridis',  # 색상 스케일 설정\n                 title='Capacity (MW) by Fuel Type and Source')\n\nfig.show()\n\n# 발전량에 대한 트리맵 생성\nfig = px.treemap(full_grouped, \n                 path=['primary_fuel', 'source'],  # 계층 구조: 연료 -> 소스\n                 values='estimated_generation_gwh',  # 트리맵의 크기: 예상 발전량\n                 color='estimated_generation_gwh',  # 색상: 발전량 크기\n                 hover_data=['capacity_mw', 'estimated_generation_gwh'],  # 호버 시 추가 정보\n                 color_continuous_scale='Plasma',  # 색상 스케일 설정\n                 title='Estimated Generation (GWh) by Fuel Type and Source')\n\nfig.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T12:37:09.704574Z","iopub.execute_input":"2025-03-19T12:37:09.704950Z","iopub.status.idle":"2025-03-19T12:37:09.944284Z","shell.execute_reply.started":"2025-03-19T12:37:09.704923Z","shell.execute_reply":"2025-03-19T12:37:09.943252Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 1. 데이터 melt: 'measure' 열에 두 가지 측정치를 구분하고, 'value' 열에 해당 값을 저장\nmelted = full_grouped.melt(id_vars=['source', 'primary_fuel'], \n                           value_vars=['capacity_mw', 'estimated_generation_gwh'],\n                           var_name='measure', value_name='value')\n\n# 2. 3단계 트리맵 생성: 첫 번째 계층은 source, 두 번째는 primary_fuel, 세 번째는 measure\nfig = px.treemap(melted,\n                 path=['source', 'primary_fuel', 'measure'],\n                 values='value',\n                 color='value',\n                 hover_data=['value'],\n                 color_continuous_scale='Viridis',\n                 title='3-Level Treemap: Source → Fuel → Measure (Capacity/Generation)')\n\nfig.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T12:47:50.347191Z","iopub.execute_input":"2025-03-19T12:47:50.347540Z","iopub.status.idle":"2025-03-19T12:47:50.467546Z","shell.execute_reply.started":"2025-03-19T12:47:50.347514Z","shell.execute_reply":"2025-03-19T12:47:50.466495Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 생키 다이어그램으로 분석해 기기\n\nimport plotly.graph_objects as go\n\nfull_grouped = power_plant.groupby(['primary_fuel','source'])[['capacity_mw', 'estimated_generation_gwh']].sum().reset_index()\nfull_grouped = full_grouped.sort_values(by='primary_fuel',ascending=False).reset_index(drop=True)\n\ndisplay(full_grouped)\n\n# 1. 데이터 변환: melt를 사용하여 'measure' 열 생성\nmelted = full_grouped.melt(id_vars=['primary_fuel','source'], \n                           value_vars=['capacity_mw', 'estimated_generation_gwh'],\n                           var_name='measure', value_name='value')\ndisplay(melted)\n\n# 2. 각 계층별 노드 목록 생성\nfuel_nodes = list(melted['primary_fuel'].unique())         # 연료 유형 노드\nsource_nodes = list(melted['source'].unique())               # 소스(발전소) 노드\nmeasure_nodes = list(melted['measure'].unique())             # 측정치 노드 (capacity_mw, estimated_generation_gwh)\n\n# 모든 노드 결합\nnode_labels= fuel_nodes + source_nodes + measure_nodes\ndisplay(node_labels)\n\n# 3. 링크 생성: 각 행마다 연료 → 소스, 소스 → 측정치 두 링크 생성\nsource_indices = []\ntarget_indices = []\nvalues = []\n\n   \n\n#iterrows(): DataFrame의 각 행을 (인덱스, 행 데이터) 튜플 형태로 반환\nfor _, row in melted.iterrows():\n    \n    # 연료에서 소스로의 링크 \n    fuel_index = fuel_nodes.index(row['primary_fuel'])  # 연료 그룹 내 인덱스\n    src_index = source_nodes.index(row['source']) + len(fuel_nodes)  # 소스 그룹의 인덱스 (연료 노드 개수 offset)\n    value = row['value']\n    \n    source_indices.append(fuel_index)\n    target_indices.append(src_index)\n    values.append(value)\n    \n    # 소스에서 측정치로의 링크\n    measure_index = measure_nodes.index(row['measure']) + len(fuel_nodes) + len(source_nodes)  # 측정치 그룹 인덱스 (연료+소스 offset)\n    source_indices.append(src_index)\n    target_indices.append(measure_index)\n    values.append(value)\n\n# 4. Sankey 다이어그램 생성\nfig = go.Figure(data=[go.Sankey(\n    node=dict(\n        pad=15,\n        thickness=20,\n        line=dict(color=\"black\", width=0.5),\n        label=node_labels,\n        color=\"lightblue\"\n    ),\n    link=dict(\n        source=source_indices,\n        target=target_indices,\n        value=values\n    )\n)])\n\nfig.update_layout(title_text=\"Sankey Diagram: Fuel Type → Source → Measure\", font_size=10)\nfig.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T13:18:29.108914Z","iopub.execute_input":"2025-03-19T13:18:29.109529Z","iopub.status.idle":"2025-03-19T13:18:29.197381Z","shell.execute_reply.started":"2025-03-19T13:18:29.109481Z","shell.execute_reply":"2025-03-19T13:18:29.196320Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#total electricity generation in gigwatthour for one year\n\ntotal_gen = power_plant['estimated_generation_gwh'].sum()\nprint('Total Generation :'+'{:.3f}'.format(total_gen)+'GW')\n\n\n# percentage of total generation in gigawatthour\n\ngeneration = (power_plant.groupby(['primary_fuel'])['estimated_generation_gwh'].sum()).to_frame()\ngeneration = generation.sort_values('estimated_generation_gwh',ascending=False)\ngeneration['percentage_of_total'] = (generation['estimated_generation_gwh']/total_gen)*100\ngeneration","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:03:09.383875Z","iopub.execute_input":"2025-03-19T14:03:09.384255Z","iopub.status.idle":"2025-03-19T14:03:09.405187Z","shell.execute_reply.started":"2025-03-19T14:03:09.384222Z","shell.execute_reply":"2025-03-19T14:03:09.403135Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 바 차트 생성\nfig, ax = plt.subplots(figsize=(10, 6))\n\n# cmap을 사용하여 높은 값은 붉은색, 낮은 값은 파란색으로 색상 적용\ncmap = plt.cm.coolwarm  # 원하는 색상맵 설정\nnorm = plt.Normalize(vmin=generation['percentage_of_total'].min(), vmax=generation['percentage_of_total'].max())  # 값 범위 정규화\nsm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)  # 색상맵을 값에 매핑\n\n# 색상 적용하여 바 그리기\nbars = ax.bar(generation.index, generation['percentage_of_total'], color=[sm.to_rgba(value) for value in generation['percentage_of_total']])\n\n# 각 막대 높이(카운트 값) 가져오기\nheights = [p.get_height() for p in ax.patches]\n\n# 최솟값 & 최댓값 계산\nymin, ymax = min(heights), max(heights)\n\n# 최솟값 라인 (빨간 점선)\nmin_line = ax.axhline(y=ymin, color='red', linestyle='dashed', linewidth=1, label=f'Min: {ymin:.2f}%')\n\n# 최댓값 라인 (파란 점선)\nmax_line = ax.axhline(y=ymax, color='blue', linestyle='dashed', linewidth=1, label=f'Max: {ymax:.2f}%')\n\n# 막대 위에 값 표시 (소수점 2자리까지)\nfor p in ax.patches:\n    ax.text(p.get_x() + p.get_width() / 2,  # x 위치\n            p.get_height() + 1,  # y 위치 (막대 높이)\n            f\"{p.get_height():.2f}%\",  # 표시할 값\n            ha='center', va='bottom', fontsize=10)  # 가운데 정렬, 폰트 크기 설정\n\n# 제목과 레이블 설정\nplt.title('Percentage of Total Electricity Generation by Fuel Type', fontsize=16, pad=10)\nplt.xlabel('Fuel Type', fontsize=14)\nplt.ylabel('Percentage of Total Generation (%)', fontsize=14)\n\n# y-axis 여백 늘리기\nplt.ylim(0, ymax + 10)  # y축 범위를 0부터 ymax + 10까지 설정하여 여백을 넓힘\n\n# 그래프 출력\nplt.xticks(ha='center')\n\n# 범례 설정\nplt.legend(loc='upper right', framealpha=1, facecolor='whitesmoke')\n\n# 레이아웃 최적화\nplt.tight_layout()\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:03:32.104279Z","iopub.execute_input":"2025-03-19T14:03:32.104692Z","iopub.status.idle":"2025-03-19T14:03:32.508194Z","shell.execute_reply.started":"2025-03-19T14:03:32.104661Z","shell.execute_reply":"2025-03-19T14:03:32.507125Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"generation = (power_plant.groupby(['source'])['estimated_generation_gwh'].sum()).to_frame()\ndisplay(generation) #to_frame()은 시리즈를 데이터 프레임 형식으로 바꾼 것임\n\ngeneration = generation.sort_values('estimated_generation_gwh',ascending=False)\ndisplay(generation)\n\ngeneration['percentage_of_total'] = (generation['estimated_generation_gwh']/total_gen)*100\ndisplay(generation)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:03:38.049526Z","iopub.execute_input":"2025-03-19T14:03:38.050192Z","iopub.status.idle":"2025-03-19T14:03:38.086305Z","shell.execute_reply.started":"2025-03-19T14:03:38.050140Z","shell.execute_reply":"2025-03-19T14:03:38.084890Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 바 차트 생성\nfig, ax = plt.subplots(figsize=(10, 6))\n\n# cmap을 사용하여 높은 값은 붉은색, 낮은 값은 파란색으로 색상 적용\ncmap = plt.cm.coolwarm  # 원하는 색상맵 설정\nnorm = plt.Normalize(vmin=generation['percentage_of_total'].min(), vmax=generation['percentage_of_total'].max())  # 값 범위 정규화\nsm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)  # 색상맵을 값에 매핑\n\n# 색상 적용하여 수평 바 그리기\nbars = ax.barh(generation.index, generation['percentage_of_total'], color=[sm.to_rgba(value) for value in generation['percentage_of_total']])\n\n# 각 막대 길이(값) 가져오기\nwidths = [p.get_width() for p in bars]\n\n# 최솟값 & 최댓값 계산 (x축 값 기준)\nxmin, xmax = min(widths), max(widths)\n\n# 최솟값 라인 (빨간 점선)\nax.axvline(x=xmin, color='red', linestyle='dashed', linewidth=1, label=f'Min: {xmin:.2f}%')\n\n# 최댓값 라인 (파란 점선)\nax.axvline(x=xmax, color='blue', linestyle='dashed', linewidth=1, label=f'Max: {xmax:.2f}%')\n\n# 막대 위에 값 표시 (소수점 2자리까지)\nfor p in bars:\n    ax.text(p.get_width() + 1,  # x 위치 (수평 방향으로)\n            p.get_y() + p.get_height() / 2,  # y 위치 (수직 방향으로)\n            f\"{p.get_width():.2f}%\",  # 표시할 값\n            va='center', fontsize=10)  # 가운데 정렬, 폰트 크기 설정\n\n# 제목과 레이블 설정\nplt.title('Percentage of Total Electricity Generation by Sources', fontsize=16, pad=10)\nplt.xlabel('Percentage of Total Generation (%)', fontsize=14)\nplt.ylabel('Sources', fontsize=14)\n\n# x-axis 여백 늘리기\nplt.xlim(0, xmax + 10)  # x축 범위를 0부터 xmax + 10까지 설정하여 여백을 넓힘\n\n# 그래프 출력\nplt.yticks(ha='right')  # y축 레이블을 보기 좋게 정렬\n\n# 범례 설정\nplt.legend(loc='upper right', framealpha=1, facecolor='whitesmoke')\n\n# 레이아웃 최적화\nplt.tight_layout()\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:05:49.758294Z","iopub.execute_input":"2025-03-19T14:05:49.758660Z","iopub.status.idle":"2025-03-19T14:05:50.204678Z","shell.execute_reply.started":"2025-03-19T14:05:49.758632Z","shell.execute_reply":"2025-03-19T14:05:50.203609Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#total production capcity \n\ntotal_cap = power_plant['capacity_mw'].sum()\nprint('Total Capcity :'+'{:.3f}'.format(total_cap)+'MW')\n\ncapcity = (power_plant.groupby(['primary_fuel'])['capacity_mw'].sum()).to_frame()\ncapcity = capcity.sort_values('capacity_mw',ascending=False)\ncapcity['percentage_of_total'] = (capcity['capacity_mw']/total_cap)*100\n\ndisplay(capcity)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:06:58.718444Z","iopub.execute_input":"2025-03-19T14:06:58.718796Z","iopub.status.idle":"2025-03-19T14:06:58.734579Z","shell.execute_reply.started":"2025-03-19T14:06:58.718765Z","shell.execute_reply":"2025-03-19T14:06:58.733345Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig = plt.gcf()\nfig.set_size_inches(10, 6)\ncolors = ['dodgerblue', 'plum', '#F0A30A','#8c564b','orange','green','yellow'] \n\nbars = capcity['percentage_of_total'].plot(kind='bar',color=colors)\n\n# 바 위에 값 표시\nfor p in bars.patches:\n    bars.text(p.get_x() + p.get_width() / 2,  # x 위치\n              p.get_height() + 1,  # y 위치 (막대 높이)\n              f\"{p.get_height():.2f}%\",  # 값 표시 (소수점 2자리로)\n              ha='center', va='bottom', fontsize=10)  # 가운데 정렬\n\nymin, ymax = plt.ylim()\nplt.ylim(0, 100)\nplt.xticks(rotation=0)\nplt.title(\"Capacity Percentage by Fuels\", pad=10, va=\"center\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:18:15.447507Z","iopub.execute_input":"2025-03-19T14:18:15.447872Z","iopub.status.idle":"2025-03-19T14:18:15.726898Z","shell.execute_reply.started":"2025-03-19T14:18:15.447842Z","shell.execute_reply":"2025-03-19T14:18:15.725744Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 전체 발전 용량 (capacity_mw의 합)\ntotal_cap = power_plant['capacity_mw'].sum()\nprint('Total Capacity :' + '{:.3f}'.format(total_cap) + ' MW')\n\n# 각 연료별 용량과 퍼센트 계산\ncapcity = (power_plant.groupby(['primary_fuel'])['capacity_mw'].sum()).to_frame()\ncapcity = capcity.sort_values('capacity_mw', ascending=False)\ncapcity['percentage_of_total'] = (capcity['capacity_mw'] / total_cap) * 100\n\n# 데이터 출력\ndisplay(capcity)\n\n#######################################################################################\n\n# 그래프 생성\n\nfig, ax1 = plt.subplots(figsize=(10, 6))\n\n# 막대 그래프 (capacity_mw) - 왼쪽 y축\ncolors = ['dodgerblue', 'plum', '#F0A30A', '#8c564b', 'orange']\nbars = ax1.bar(capcity.index, capcity['capacity_mw'], color=colors)\n\n# 바 위에 값 표시 (capacity_mw)\nfor p in bars:\n    ax1.text(p.get_x() + p.get_width() / 2, p.get_height() + 100,  # x 위치, y 위치\n             f\"{p.get_height():,.0f} MW\",  # 표시할 값\n             ha='center', va='bottom', fontsize=10)  # 가운데 정렬\n\n# 왼쪽 y축 설정\nax1.set_xlabel('Fuel Type', fontsize=14)\nax1.set_ylabel('Capacity (MW)', fontsize=14)\nax1.set_xticklabels(capcity.index, rotation=0)\nax1.set_ylim(0, capcity['capacity_mw'].max() + 1000)  # y축 여백 추가\n\n\n# 오른쪽 y축 (percentage_of_total) - 선 그래프\nax2 = ax1.twinx()  # ax1의 오른쪽에 y축 추가\nax2.plot(capcity.index, capcity['percentage_of_total'], color='green', marker='o', label='Percentage of Total', linewidth=2, alpha=0.5)\n\n# 오른쪽 y축 설정\nax2.set_ylabel('Percentage of Total Generation (%)', fontsize=14)\nax2.set_ylim(0, 100)  # 퍼센트는 0부터 100까지\n\n# 제목\nplt.title(\"Capacity and Percentage by Fuel Type\", pad=10)\n\n# 범례 (선 그래프에만 범례 추가)\nax2.legend(loc='upper right')\n\n# 레이아웃 최적화\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:32:07.148515Z","iopub.execute_input":"2025-03-19T14:32:07.148900Z","iopub.status.idle":"2025-03-19T14:32:07.682594Z","shell.execute_reply.started":"2025-03-19T14:32:07.148869Z","shell.execute_reply":"2025-03-19T14:32:07.681567Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"capcity = (power_plant.groupby(['source'])['capacity_mw'].sum()).to_frame()\ncapcity = capcity.sort_values('capacity_mw',ascending=False)\ncapcity['percentage_of_total'] = (capcity['capacity_mw']/total_cap)*100\ncapcity","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:32:55.901873Z","iopub.execute_input":"2025-03-19T14:32:55.902203Z","iopub.status.idle":"2025-03-19T14:32:55.918469Z","shell.execute_reply.started":"2025-03-19T14:32:55.902176Z","shell.execute_reply":"2025-03-19T14:32:55.917342Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#######################################################################################\nfrom textwrap import wrap\n\n# 그래프 생성\n\nfig, ax1 = plt.subplots(figsize=(20, 5))\n\n# 막대 그래프 (capacity_mw) - 왼쪽 y축\ncolors = ['dodgerblue', 'plum', '#F0A30A', '#8c564b', 'orange']\nbars = ax1.bar(capcity.index, capcity['capacity_mw'], color=colors)\n\n# 바 위에 값 표시 (capacity_mw)\nfor p in bars:\n    ax1.text(p.get_x() + p.get_width() / 2, p.get_height() + 100,  # x 위치, y 위치\n             f\"{p.get_height():,.0f} MW\",  # 표시할 값\n             ha='center', va='bottom', fontsize=10)  # 가운데 정렬\n\n# 왼쪽 y축 설정\nax1.set_xlabel('source', fontsize=14)\nax1.set_ylabel('Capacity (MW)', fontsize=14)\nax1.set_ylim(0, capcity['capacity_mw'].max() + 1000)  # y축 여백 추가\n\n# 라벨 길이가 너무 길때\nax1.set_xticklabels(['\\n'.join(wrap(label, width=10)) for label in capcity.index], rotation=0)\n\n# 오른쪽 y축 (percentage_of_total) - 선 그래프\nax2 = ax1.twinx()  # ax1의 오른쪽에 y축 추가\nax2.plot(capcity.index, capcity['percentage_of_total'], color='green', marker='o', label='Percentage of Total', linewidth=2, alpha=0.5)\n\n# 오른쪽 y축 설정\nax2.set_ylabel('Percentage of Total Generation (%)', fontsize=14)\nax2.set_ylim(0, 100)  # 퍼센트는 0부터 100까지\n\n# 제목\nplt.title(\"Capacity and Percentage by source\", pad=10)\n\n# 범례 (선 그래프에만 범례 추가)\nax2.legend(loc='upper right')\n\n# 레이아웃 최적화\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:42:19.226018Z","iopub.execute_input":"2025-03-19T14:42:19.226371Z","iopub.status.idle":"2025-03-19T14:42:19.923871Z","shell.execute_reply.started":"2025-03-19T14:42:19.226343Z","shell.execute_reply":"2025-03-19T14:42:19.922818Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Second Part\n","metadata":{}},{"cell_type":"code","source":"\"\"\"\n1. plot_points_on_map\n이 함수는 데이터프레임의 특정 범위(행)에서 위도 및 경도 값을 사용해 folium 지도 위에 마커를 표시하는 함수입니다.\n매개변수:\ndataframe: 마커를 추가할 데이터프레임\nbegin_index, end_index: 데이터프레임에서 선택할 범위의 인덱스 (슬라이싱용)\nlatitude_column, longitude_column: 위도 및 경도 값을 포함하는 열 이름\nlatitude_value, longitude_value: 지도의 중심 좌표로 사용할 위도 및 경도 값\nzoom: 지도의 줌 레벨\n기능: 주어진 인덱스 범위 내에서 각 행에 대해 마커를 추가하고, 마커에는 primary_fuel 열의 값을 팝업으로 표시합니다.\n결과: 지도 객체를 반환합니다.\n\"\"\"\n\ndef plot_points_on_map(dataframe,begin_index,end_index,latitude_column,latitude_value,longitude_column,longitude_value,zoom):\n    df = dataframe[begin_index:end_index]\n    location = [latitude_value,longitude_value]\n    plot = folium.Map(location=location,zoom_start=zoom)\n    for i in range(0,len(df)):\n        popup = folium.Popup(str(df.primary_fuel[i:i+1]))\n        folium.Marker([df[latitude_column].iloc[i],df[longitude_column].iloc[i]],popup=popup).add_to(plot)\n    return(plot)\n\n\n\n\n\"\"\"\n2. overlay_image_on_puerto_rico\n이 함수는 Puerto Rico 지역의 특정 이미지 파일을 지도에 오버레이하는 함수입니다.\nrasterio 라이브러리를 사용해 이미지의 특정 밴드를 읽고 이를 folium 지도에 오버레이합니다.\n\n매개변수:\nfile_name: 오버레이할 이미지 파일 경로\nband_layer: 사용할 밴드의 번호 (이미지 파일 내 특정 레이어)\n기능: 지정된 이미지의 밴드를 읽고, 그 밴드를 특정 위도/경도 경계 범위(푸에르토리코)에 맞춰 오버레이합니다.\nfolium의 ImageOverlay를 사용하여 지도 위에 이미지를 시각화합니다.\n결과: 지도 객체를 반환합니다.\n\"\"\"\n\ndef overlay_image_on_puerto_rico(file_name,band_layer):\n    band = rio.open(file_name).read(band_layer)\n    m = folium.Map([lat, lon], zoom_start=8)\n    folium.raster_layers.ImageOverlay(\n        image=band,\n        bounds = [[18.6,-67.3,],[17.9,-65.2]],\n        colormap=lambda x: (1, 0, 0, x),\n    ).add_to(m)\n    return m\n\n\n\n\"\"\"\n3. plot_scaled\n이 함수는 주어진 파일 데이터를 5-95% 범위로 정규화하여 이미지를 표시합니다.\n\n매개변수:\nfile_name: 이미지를 표시할 데이터 (이미지 배열)\n기능: 입력 데이터를 5%에서 95% 사이의 값으로 정규화하고 imshow로 그레이스케일로 이미지를 출력합니다.\n결과: 정규화된 이미지를 화면에 표시합니다.\n\"\"\"\n\ndef plot_scaled(file_name):\n    vmin, vmax = np.nanpercentile(file_name, (5,95))  # 5-95% stretch\n    img_plt = plt.imshow(file_name, cmap='gray', vmin=vmin, vmax=vmax)\n    plt.show()\n\n\n\n\"\"\"\n4. split_column_into_new_columns\n이 함수는 데이터프레임의 한 열에서 일부 문자열을 추출하여 새로운 열에 저장하는 함수입니다.\n\n매개변수:\ndataframe: 데이터를 포함한 데이터프레임\ncolumn_to_split: 데이터를 나눌 원본 열 이름\nnew_column_one: 새로운 열의 이름\nbegin_column_one, end_column_one: 추출할 문자열의 시작과 끝 인덱스\n기능: 주어진 열에서 문자열을 추출하여 new_column_one에 저장합니다. 각 행에 대해 지정된 범위의 문자열을 자르고 새로운 열에 할당합니다.\n결과: 새로운 열이 추가된 데이터프레임을 반환합니다.\n\"\"\"\n\ndef split_column_into_new_columns(dataframe,column_to_split,new_column_one,begin_column_one,end_column_one):\n    for i in range(0, len(dataframe)):\n        dataframe.loc[i, new_column_one] = dataframe.loc[i, column_to_split][begin_column_one:end_column_one]\n    return dataframe\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:42:40.058151Z","iopub.execute_input":"2025-03-19T14:42:40.058493Z","iopub.status.idle":"2025-03-19T14:42:40.070354Z","shell.execute_reply.started":"2025-03-19T14:42:40.058466Z","shell.execute_reply":"2025-03-19T14:42:40.069136Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pd.set_option('display.max_colwidth', None)\n\npower_plant = pd.read_csv('/kaggle/input/ds4g-environmental-insights-explorer/eie_data/gppd/gppd_120_pr.csv')\ngeo = power_plant[['.geo']]\n\ngeo","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:50:41.240184Z","iopub.execute_input":"2025-03-19T14:50:41.240586Z","iopub.status.idle":"2025-03-19T14:50:41.265589Z","shell.execute_reply.started":"2025-03-19T14:50:41.240555Z","shell.execute_reply":"2025-03-19T14:50:41.264354Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# 위 데이터에서는 위도/경도가 아닌 경도/위도 순서로 표시되어 있음.\npower_plant = split_column_into_new_columns(power_plant,'.geo','longitude',31,48) #경도\npower_plant = split_column_into_new_columns(power_plant,'.geo','latitude',50,66) #위도\n\npower_plant['latitude'] = power_plant['latitude'].astype(float)\n\na = np.array(power_plant['latitude'].values.tolist()) # 18 instead of 8\n\npower_plant['latitude'] = np.where(a < 10, a+10, a).tolist() \n\nlat=18.200178; lon=-66.664513\n\nplot_points_on_map(power_plant,0,425,'latitude',18,'longitude',-66.4, 9.3)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T15:00:47.241948Z","iopub.execute_input":"2025-03-19T15:00:47.242269Z","iopub.status.idle":"2025-03-19T15:00:47.339422Z","shell.execute_reply.started":"2025-03-19T15:00:47.242241Z","shell.execute_reply":"2025-03-19T15:00:47.338354Z"}},"outputs":[],"execution_count":null}]}