DV 12주차

지리정보시각화
FOLIUM
FLOTLY
Author

김보람

Published

November 21, 2022

12주차(1) _ 1121

!pip install folium
Requirement already satisfied: folium in /home/coco/anaconda3/envs/py38/lib/python3.8/site-packages (0.14.0)
Requirement already satisfied: requests in /home/coco/anaconda3/envs/py38/lib/python3.8/site-packages (from folium) (2.28.2)
Requirement already satisfied: numpy in /home/coco/anaconda3/envs/py38/lib/python3.8/site-packages (from folium) (1.24.2)
Requirement already satisfied: jinja2>=2.9 in /home/coco/anaconda3/envs/py38/lib/python3.8/site-packages (from folium) (3.1.2)
Requirement already satisfied: branca>=0.6.0 in /home/coco/anaconda3/envs/py38/lib/python3.8/site-packages (from folium) (0.6.0)
Requirement already satisfied: MarkupSafe>=2.0 in /home/coco/anaconda3/envs/py38/lib/python3.8/site-packages (from jinja2>=2.9->folium) (2.1.1)
Requirement already satisfied: idna<4,>=2.5 in /home/coco/anaconda3/envs/py38/lib/python3.8/site-packages (from requests->folium) (3.4)
Requirement already satisfied: certifi>=2017.4.17 in /home/coco/anaconda3/envs/py38/lib/python3.8/site-packages (from requests->folium) (2022.12.7)
Requirement already satisfied: charset-normalizer<4,>=2 in /home/coco/anaconda3/envs/py38/lib/python3.8/site-packages (from requests->folium) (2.1.1)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in /home/coco/anaconda3/envs/py38/lib/python3.8/site-packages (from requests->folium) (1.26.14)
import numpy as np
import pandas as pd
import folium
import folium.plugins

folium

- ref: folium

-Leaflet.js + Python \(\to\) folium

  • 데이터전처리: 파이썬이용

  • 시각화: Leaflet.js 이용

- Leaflet.js 란?

  • 지리정보시각화를 위해 개발된 자바스크립트 라이브러리

- 이런 패키지특징: 사용방법을 익히기 어렵다.

  • 메뉴얼이 정리되어 있지 않음

folium: 기본지도 그리기

folium.Map()

- global view

folium.Map(scrollWheelZoom=False)
Make this Notebook Trusted to load map: File -> Trust Notebook

- 줌스크롤을 False 시키는 방법: scrollWheelZoom=False

- 이 옵션을 확인하려면? (1) 도움말 (2) folium 공식홈페이지 (3) Leaflet 공식홈페이지

folium.Map?
Init signature:
folium.Map(
    location=None,
    width='100%',
    height='100%',
    left='0%',
    top='0%',
    position='relative',
    tiles='OpenStreetMap',
    attr=None,
    min_zoom=0,
    max_zoom=18,
    zoom_start=10,
    min_lat=-90,
    max_lat=90,
    min_lon=-180,
    max_lon=180,
    max_bounds=False,
    crs='EPSG3857',
    control_scale=False,
    prefer_canvas=False,
    no_touch=False,
    disable_3d=False,
    png_enabled=False,
    zoom_control=True,
    **kwargs,
)
Docstring:     
Create a Map with Folium and Leaflet.js
Generate a base map of given width and height with either default
tilesets or a custom tileset URL. The following tilesets are built-in
to Folium. Pass any of the following to the "tiles" keyword:
    - "OpenStreetMap"
    - "Mapbox Bright" (Limited levels of zoom for free tiles)
    - "Mapbox Control Room" (Limited levels of zoom for free tiles)
    - "Stamen" (Terrain, Toner, and Watercolor)
    - "Cloudmade" (Must pass API key)
    - "Mapbox" (Must pass API key)
    - "CartoDB" (positron and dark_matter)
You can pass a custom tileset to Folium by passing a
:class:`xyzservices.TileProvider` or a Leaflet-style
URL to the tiles parameter: ``http://{s}.yourtiles.com/{z}/{x}/{y}.png``.
You can find a list of free tile providers here:
``http://leaflet-extras.github.io/leaflet-providers/preview/``.
Be sure to check their terms and conditions and to provide attribution
with the `attr` keyword.
Parameters
----------
location: tuple or list, default None
    Latitude and Longitude of Map (Northing, Easting).
width: pixel int or percentage string (default: '100%')
    Width of the map.
height: pixel int or percentage string (default: '100%')
    Height of the map.
tiles: str or TileLayer or :class:`xyzservices.TileProvider`, default 'OpenStreetMap'
    Map tileset to use. Can choose from a list of built-in tiles,
    pass a :class:`xyzservices.TileProvider`,
    pass a custom URL, pass a TileLayer object,
    or pass `None` to create a map without tiles.
    For more advanced tile layer options, use the `TileLayer` class.
min_zoom: int, default 0
    Minimum allowed zoom level for the tile layer that is created.
max_zoom: int, default 18
    Maximum allowed zoom level for the tile layer that is created.
zoom_start: int, default 10
    Initial zoom level for the map.
attr: string, default None
    Map tile attribution; only required if passing custom tile URL.
crs : str, default 'EPSG3857'
    Defines coordinate reference systems for projecting geographical points
    into pixel (screen) coordinates and back.
    You can use Leaflet's values :
    * EPSG3857 : The most common CRS for online maps, used by almost all
    free and commercial tile providers. Uses Spherical Mercator projection.
    Set in by default in Map's crs option.
    * EPSG4326 : A common CRS among GIS enthusiasts.
    Uses simple Equirectangular projection.
    * EPSG3395 : Rarely used by some commercial tile providers.
    Uses Elliptical Mercator projection.
    * Simple : A simple CRS that maps longitude and latitude into
    x and y directly. May be used for maps of flat surfaces
    (e.g. game maps). Note that the y axis should still be inverted
    (going from bottom to top).
control_scale : bool, default False
    Whether to add a control scale on the map.
prefer_canvas : bool, default False
    Forces Leaflet to use the Canvas back-end (if available) for
    vector layers instead of SVG. This can increase performance
    considerably in some cases (e.g. many thousands of circle
    markers on the map).
no_touch : bool, default False
    Forces Leaflet to not use touch events even if it detects them.
disable_3d : bool, default False
    Forces Leaflet to not use hardware-accelerated CSS 3D
    transforms for positioning (which may cause glitches in some
    rare environments) even if they're supported.
zoom_control : bool, default True
    Display zoom controls on the map.
**kwargs
    Additional keyword arguments are passed to Leaflets Map class:
    https://leafletjs.com/reference.html#map
Returns
-------
Folium Map Object
Examples
--------
>>> m = folium.Map(location=[45.523, -122.675], width=750, height=500)
>>> m = folium.Map(location=[45.523, -122.675], tiles="cartodb positron")
>>> m = folium.Map(
...     location=[45.523, -122.675],
...     zoom_start=2,
...     tiles="https://api.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token=mytoken",
...     attr="Mapbox attribution",
... )
File:           ~/anaconda3/envs/py38/lib/python3.8/site-packages/folium/folium.py
Type:           type
Subclasses:     

- location과 scale을 조정하는 방법

  • 35.8475, 127.1305 # 전북대 자연대 본관

  • 35.8468, 127.1294 # 전북대 분수대

folium.Map(scrollWheelZoom=False,
          location = [35.8475, 127.1305],
          zoom_start=20)
Make this Notebook Trusted to load map: File -> Trust Notebook
folium.Map(scrollWheelZoom=False,
          location = [35.8475, 127.1305], #자연대본관이 센터
          zoom_start=15)
Make this Notebook Trusted to load map: File -> Trust Notebook

- tiles 옵션을 주어서 지도의 외형을 변경하여 보자.

  • tiles=“OpenStreetMap”

  • tiles=“Stamen Terrain”, tiles=“Stamen Toner”, tiles=“Stamen Watercolor”

  • tiles="CartoDB positron", tiles=“CartoDB dark_matter”

folium.Map(scrollWheelZoom=False,
          location = [35.8475, 127.1305],
          zoom_start=15,
          tiles="Stamen Terrain")
Make this Notebook Trusted to load map: File -> Trust Notebook

folium: 기본지도 위에 마커 추가

folium.Marker()

- 마커생성

jbnu = folium.Marker(
    location = [35.8475, 127.1305]
)

folium.Marker 는 클래스

m = folium.Map(scrollWheelZoom=False,
          location = [35.8475, 127.1305],
          zoom_start=14,
          tiles="CartoDB positron")

folium.Map 도 클래스

jbnu.add_to(m)
<folium.map.Marker at 0x7f1e34897b50>
m
Make this Notebook Trusted to load map: File -> Trust Notebook
home = folium.Marker(
    location = [35.8368, 127.1118] # 서신동
)
home.add_to(m)
<folium.map.Marker at 0x7f1e34897220>
m
Make this Notebook Trusted to load map: File -> Trust Notebook

마커에 팝업내용 추가

m = folium.Map(
    scrollWheelZoom=False,
    location = [35.8475,127.1305], # 자연대본관  
    zoom_start=14,
    tiles="CartoDB positron"
)
jbnu = folium.Marker(
    location = [35.8475,127.1305], # 자연대본관  
    popup = "JBNU"
)
home = folium.Marker(
    location = [35.8368, 127.1118], # 서신동
    popup = "HOME",
    tooltip = "클릭해주세요"
)
jbnu.add_to(m)
home.add_to(m)
m
Make this Notebook Trusted to load map: File -> Trust Notebook

마커의 아이콘 변경

- folium.Marker()에서 icon=folium.Icon(color=‘red’,icon=‘university’,prefix=‘fa’) 와 같은 식으로 옵션을 추가

  • icon=‘university’ 대신에 `street-view’,‘tree’,‘plane’,‘bell’ 등을 추가할 수 있음.

  • 아이콘들은 여기 참고. ’glyphicon glyphicon-” 부분을 제외한 문자열을 넣으면 된다.

m = folium.Map(
    scrollWheelZoom=False,
    location = [35.8475,127.1305], # 자연대본관  
    zoom_start=14,
    tiles="CartoDB positron"
)
jbnu = folium.Marker(
    location = [35.8475,127.1305], # 자연대본관  
    icon=folium.Icon(color='red',icon='university',prefix='fa'),
    popup = "JBNU"
)
home = folium.Marker(
    location = [35.8368, 127.1118], # 서신동
    popup = "HOME",
    tooltip = "클릭해주세요"
)
jbnu.add_to(m)
home.add_to(m)
m
Make this Notebook Trusted to load map: File -> Trust Notebook

마커의 팝업내용 HTML넣기(1)

- “JBNU” 대신에 "<h2> JBNU </h2><br>"

- “HOME” 대신에 "<h5> HOME </h5><br>"

m = folium.Map(
    scrollWheelZoom=False,
    location = [35.8475,127.1305], # 자연대본관  
    zoom_start=14,
    tiles="CartoDB positron"
)
jbnu = folium.Marker(
    location = [35.8475,127.1305], # 자연대본관  
    icon=folium.Icon(color='red',icon='university',prefix='fa'),
    popup = "<h2> JBNU </h2><br>"
)
home = folium.Marker(
    location = [35.8368, 127.1118], # 서신동
    popup = "<h5> HOME </h5><br>",
    tooltip = "클릭해주세요"
)
jbnu.add_to(m)
home.add_to(m)
m
Make this Notebook Trusted to load map: File -> Trust Notebook

마커의 팝업내용 HTML넣기(2)

  • 데이터프레임을 HTML로 바꾸어서 넣기
_df=pd.DataFrame({'year':[2019,2020,2021,2022],'students':[35,30,33,26]})
_df
year students
0 2019 35
1 2020 30
2 2021 33
3 2022 26
_df.to_html()
year students
0 2019 35
1 2020 30
2 2021 33
3 2022 26
m = folium.Map(
    scrollWheelZoom=False,
    location = [35.8475,127.1305], # 자연대본관  
    zoom_start=14,
    tiles="CartoDB positron"
)
jbnu = folium.Marker(
    location = [35.8475,127.1305], # 자연대본관  
    icon=folium.Icon(color='red',icon='university',prefix='fa'),
    popup = _df.to_html()
)
home = folium.Marker(
    location = [35.8368, 127.1118], # 서신동
    popup = "<h5> HOME </h5><br>" + _df.to_html(),
    tooltip = "클릭해주세요"
)
jbnu.add_to(m)
home.add_to(m)
m
Make this Notebook Trusted to load map: File -> Trust Notebook

마커의 팝업내용 HTML넣기(3)

  • 데이터프레임을 HTML로 바꾸어서 넣어보자.

  • 팝업시 크기를 조절할 수 있게 해보자. (folium.IFrame, folium.Popup 이용)

_iframe = folium.IFrame('<h2> JBNU </h2><br>'+_df.to_html(),width=150,height=200)
_popup = folium.Popup(_iframe)
m = folium.Map(
    scrollWheelZoom=False,
    location = [35.8475,127.1305], # 자연대본관  
    zoom_start=14,
    tiles="CartoDB positron"
)
jbnu = folium.Marker(
    location = [35.8475,127.1305], # 자연대본관  
    icon=folium.Icon(color='red',icon='university',prefix='fa'),
    popup = _popup
)
home = folium.Marker(
    location = [35.8368, 127.1118], # 집 
    popup = "<h5> HOME </h5><br>",
    tooltip = "클릭해주세요"
)
jbnu.add_to(m)
home.add_to(m)
m
Make this Notebook Trusted to load map: File -> Trust Notebook

마커의 팝업내용 HTML넣기(4)

  • 논리구조상 HTML 오브젝트를 아무거나 넣을 수 있음 \(\to\) 그림도 넣을 수 있을까?

  • 그림파일을 HTML로 바꾸어서 넣어보자.

import matplotlib.pyplot as plt
_df.plot.line(x='year',y='students')
fig = plt.gcf()

fig.savefig?
Signature: fig.savefig(fname, *, transparent=None, **kwargs)
Docstring:
Save the current figure.
Call signature::
  savefig(fname, *, dpi='figure', format=None, metadata=None,
          bbox_inches=None, pad_inches=0.1,
          facecolor='auto', edgecolor='auto',
          backend=None, **kwargs
         )
The available output formats depend on the backend being used.
Parameters
----------
fname : str or path-like or binary file-like
    A path, or a Python file-like object, or
    possibly some backend-dependent object such as
    `matplotlib.backends.backend_pdf.PdfPages`.
    If *format* is set, it determines the output format, and the file
    is saved as *fname*.  Note that *fname* is used verbatim, and there
    is no attempt to make the extension, if any, of *fname* match
    *format*, and no extension is appended.
    If *format* is not set, then the format is inferred from the
    extension of *fname*, if there is one.  If *format* is not
    set and *fname* has no extension, then the file is saved with
    :rc:`savefig.format` and the appropriate extension is appended to
    *fname*.
Other Parameters
----------------
dpi : float or 'figure', default: :rc:`savefig.dpi`
    The resolution in dots per inch.  If 'figure', use the figure's
    dpi value.
format : str
    The file format, e.g. 'png', 'pdf', 'svg', ... The behavior when
    this is unset is documented under *fname*.
metadata : dict, optional
    Key/value pairs to store in the image metadata. The supported keys
    and defaults depend on the image format and backend:
    - 'png' with Agg backend: See the parameter ``metadata`` of
      `~.FigureCanvasAgg.print_png`.
    - 'pdf' with pdf backend: See the parameter ``metadata`` of
      `~.backend_pdf.PdfPages`.
    - 'svg' with svg backend: See the parameter ``metadata`` of
      `~.FigureCanvasSVG.print_svg`.
    - 'eps' and 'ps' with PS backend: Only 'Creator' is supported.
bbox_inches : str or `.Bbox`, default: :rc:`savefig.bbox`
    Bounding box in inches: only the given portion of the figure is
    saved.  If 'tight', try to figure out the tight bbox of the figure.
pad_inches : float, default: :rc:`savefig.pad_inches`
    Amount of padding around the figure when bbox_inches is 'tight'.
facecolor : color or 'auto', default: :rc:`savefig.facecolor`
    The facecolor of the figure.  If 'auto', use the current figure
    facecolor.
edgecolor : color or 'auto', default: :rc:`savefig.edgecolor`
    The edgecolor of the figure.  If 'auto', use the current figure
    edgecolor.
backend : str, optional
    Use a non-default backend to render the file, e.g. to render a
    png file with the "cairo" backend rather than the default "agg",
    or a pdf file with the "pgf" backend rather than the default
    "pdf".  Note that the default backend is normally sufficient.  See
    :ref:`the-builtin-backends` for a list of valid backends for each
    file format.  Custom backends can be referenced as "module://...".
orientation : {'landscape', 'portrait'}
    Currently only supported by the postscript backend.
papertype : str
    One of 'letter', 'legal', 'executive', 'ledger', 'a0' through
    'a10', 'b0' through 'b10'. Only supported for postscript
    output.
transparent : bool
    If *True*, the Axes patches will all be transparent; the
    Figure patch will also be transparent unless *facecolor*
    and/or *edgecolor* are specified via kwargs.
    If *False* has no effect and the color of the Axes and
    Figure patches are unchanged (unless the Figure patch
    is specified via the *facecolor* and/or *edgecolor* keyword
    arguments in which case those colors are used).
    The transparency of these patches will be restored to their
    original values upon exit of this function.
    This is useful, for example, for displaying
    a plot on top of a colored background on a web page.
bbox_extra_artists : list of `~matplotlib.artist.Artist`, optional
    A list of extra artists that will be considered when the
    tight bbox is calculated.
pil_kwargs : dict, optional
    Additional keyword arguments that are passed to
    `PIL.Image.Image.save` when saving the figure.
File:      ~/anaconda3/envs/py38/lib/python3.8/site-packages/matplotlib/figure.py
Type:      method
fig.savefig('test.png')
  • 저장한 그림파일을 HTML로 바꾸기 위해서 base64 가져오기
import base64
_encoded = base64.b64encode(open('test.png','rb').read())
_myhtml = '<img src="data:image/png;base64,{}">'.format
_iframe = folium.IFrame(_myhtml(_encoded.decode('UTF-8')),width=400,height=300)
_popup = folium.Popup(_iframe)
m = folium.Map(
    scrollWheelZoom=False,
    location = [35.8475,127.1305], # 자연대본관  
    zoom_start=14,
    tiles="CartoDB positron"
)
jbnu = folium.Marker(
    location = [35.8475,127.1305], # 자연대본관  
    icon=folium.Icon(color='red',icon='university',prefix='fa'),
    popup = _popup
)
home = folium.Marker(
    location = [35.8368, 127.1118], # 집 
    popup = "<h5> HOME </h5><br>",
    tooltip = "클릭해주세요"
)
jbnu.add_to(m)
home.add_to(m)
m
Make this Notebook Trusted to load map: File -> Trust Notebook

folium.CircleMarker()

- 서클마커 생성

folium.CircleMarker?
Init signature:
folium.CircleMarker(
    location=None,
    radius=10,
    popup=None,
    tooltip=None,
    **kwargs,
)
Docstring:     
A circle of a fixed size with radius specified in pixels.
See :func:`folium.vector_layers.path_options` for the `Path` options.
Parameters
----------
location: tuple[float, float]
    Latitude and Longitude pair (Northing, Easting)
popup: string or folium.Popup, default None
    Input text or visualization for object displayed when clicking.
tooltip: str or folium.Tooltip, default None
    Display a text when hovering over the object.
radius: float, default 10
    Radius of the circle marker, in pixels.
**kwargs
    Other valid (possibly inherited) options. See:
    https://leafletjs.com/reference.html#circlemarker
File:           ~/anaconda3/envs/py38/lib/python3.8/site-packages/folium/vector_layers.py
Type:           type
Subclasses:     
m = folium.Map(
    scrollWheelZoom=False,
    location = [35.8475,127.1305], # 자연대본관  
    zoom_start=14,
    tiles="CartoDB positron"
)
jbnu = folium.CircleMarker(
    location = [35.8475,127.1305], 
    popup = "JBNU"
)
jbnu.add_to(m)
m
Make this Notebook Trusted to load map: File -> Trust Notebook

서클마커의 색상 및 크기 변경

m = folium.Map(
    scrollWheelZoom=False,
    location = [35.8475,127.1305], # 자연대본관  
    zoom_start=14,
    tiles="CartoDB positron"
)
jbnu = folium.CircleMarker(
    location = [35.8475,127.1305], 
    popup = "JBNU",
    radius = 20,
    color='red'
)
jbnu.add_to(m)
m
Make this Notebook Trusted to load map: File -> Trust Notebook

서클마커 테두리 삭제 및 fill

m = folium.Map(
    scrollWheelZoom=False,
    location = [35.8475,127.1305], # 자연대본관  
    zoom_start=14,
    tiles="CartoDB positron"
)
jbnu = folium.CircleMarker(
    location = [35.8475,127.1305], 
    popup = "JBNU",
    radius = 20,
    color=None,
    fill=True,
    fill_color='blue'
)
jbnu.add_to(m)
m
Make this Notebook Trusted to load map: File -> Trust Notebook

folium: heatmap

folium.plugins.HeatMap()

- Heatmap은 폴리움에서 데이터 시각화를 하기에 적합한 기본도구임

hetmap : 변수가 nx3(or2)의 형태로 저장되어야함. 위치정보, 색깔

data = np.random.multivariate_normal(mean=[28,77],cov=[[5,0],[0,5]],size=30)
data
array([[31.87656853, 79.34269628],
       [29.53746796, 78.20520413],
       [28.44741835, 75.25393877],
       [25.18000843, 77.29323413],
       [26.5655878 , 75.04112898],
       [30.26974765, 75.29758731],
       [27.42810962, 80.27026743],
       [26.03407782, 75.03340673],
       [23.13286124, 74.55639991],
       [30.56378882, 77.03833101],
       [25.94630147, 79.58208503],
       [30.41785934, 73.81735875],
       [26.84184867, 77.71415394],
       [26.95763342, 77.60550267],
       [25.50607312, 75.18693209],
       [26.56490414, 72.84899181],
       [28.61513069, 78.29572699],
       [28.91892598, 79.02845267],
       [24.9521176 , 77.88967077],
       [29.61739757, 77.146509  ],
       [28.58079145, 75.09665559],
       [27.75159191, 77.78093079],
       [30.34745529, 75.46061955],
       [30.48379849, 78.63122606],
       [31.47434772, 77.57715823],
       [28.52014748, 72.95015858],
       [27.57394214, 72.24002852],
       [27.4789938 , 74.16576952],
       [29.28250426, 77.94044247],
       [30.59382987, 77.77600336]])
folium.plugins.HeatMap?
Init signature:
folium.plugins.HeatMap(
    data,
    name=None,
    min_opacity=0.5,
    max_zoom=18,
    radius=25,
    blur=15,
    gradient=None,
    overlay=True,
    control=True,
    show=True,
    **kwargs,
)
Docstring:     
Create a Heatmap layer
Parameters
----------
data : list of points of the form [lat, lng] or [lat, lng, weight]
    The points you want to plot.
    You can also provide a numpy.array of shape (n,2) or (n,3).
name : string, default None
    The name of the Layer, as it will appear in LayerControls.
min_opacity  : default 1.
    The minimum opacity the heat will start at.
max_zoom : default 18
    Zoom level where the points reach maximum intensity (as intensity
    scales with zoom), equals maxZoom of the map by default
radius : int, default 25
    Radius of each "point" of the heatmap
blur : int, default 15
    Amount of blur
gradient : dict, default None
    Color gradient config. e.g. {0.4: 'blue', 0.65: 'lime', 1: 'red'}
overlay : bool, default True
    Adds the layer as an optional overlay (True) or the base layer (False).
control : bool, default True
    Whether the Layer will be included in LayerControls.
show: bool, default True
    Whether the layer will be shown on opening (only for overlays).
File:           ~/anaconda3/envs/py38/lib/python3.8/site-packages/folium/plugins/heat_map.py
Type:           type
Subclasses:     
folium.plugins.HeatMap(data)
<folium.plugins.heat_map.HeatMap at 0x7f1e3201e250>
m = folium.Map(
    scrollWheelZoom=False,
    location = [28,77],
    zoom_start=5
)
folium.plugins.HeatMap(data).add_to(m)
m
Make this Notebook Trusted to load map: File -> Trust Notebook
m = folium.Map(
    scrollWheelZoom=False,
    location = [28,77],
    zoom_start=5
)
folium.plugins.HeatMap(data,
    radius=11
).add_to(m)
m
Make this Notebook Trusted to load map: File -> Trust Notebook

folium: heatmap animation

folium.plugins.HeatMapWithTime()

data1 = np.random.multivariate_normal(mean=[28,77],cov=[[5,0],[0,5]],size=20)
data2 = np.random.multivariate_normal(mean=[25,80],cov=[[5,0],[0,5]],size=20)
data3 = np.random.multivariate_normal(mean=[31,70],cov=[[5,0],[0,5]],size=20)
data = np.array([data1,data2,data3])
m = folium.Map(
    scrollWheelZoom=False,
    location = [28,77],
    zoom_start=5
)
folium.plugins.HeatMapWithTime(
    data.tolist(),
    index=['t1','t2','t3'], # time_index 
    radius=15,
).add_to(m)
m
Make this Notebook Trusted to load map: File -> Trust Notebook

예제: earthquakes

Step1: Pandas 정리

df=pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/earthquakes-23k.csv')
df
Date Latitude Longitude Magnitude
0 01/02/1965 19.2460 145.6160 6.0
1 01/04/1965 1.8630 127.3520 5.8
2 01/05/1965 -20.5790 -173.9720 6.2
3 01/08/1965 -59.0760 -23.5570 5.8
4 01/09/1965 11.9380 126.4270 5.8
... ... ... ... ...
23407 12/28/2016 38.3917 -118.8941 5.6
23408 12/28/2016 38.3777 -118.8957 5.5
23409 12/28/2016 36.9179 140.4262 5.9
23410 12/29/2016 -9.0283 118.6639 6.3
23411 12/30/2016 37.3973 141.4103 5.5

23412 rows × 4 columns

df.Date
0        01/02/1965
1        01/04/1965
2        01/05/1965
3        01/08/1965
4        01/09/1965
            ...    
23407    12/28/2016
23408    12/28/2016
23409    12/28/2016
23410    12/29/2016
23411    12/30/2016
Name: Date, Length: 23412, dtype: object
' 01/02/1965'.split('/')[-1]
'1965'
df.assign(Year = list(map(lambda x: x.split('/')[-1], df.Date)))
Date Latitude Longitude Magnitude Year
0 01/02/1965 19.2460 145.6160 6.0 1965
1 01/04/1965 1.8630 127.3520 5.8 1965
2 01/05/1965 -20.5790 -173.9720 6.2 1965
3 01/08/1965 -59.0760 -23.5570 5.8 1965
4 01/09/1965 11.9380 126.4270 5.8 1965
... ... ... ... ... ...
23407 12/28/2016 38.3917 -118.8941 5.6 2016
23408 12/28/2016 38.3777 -118.8957 5.5 2016
23409 12/28/2016 36.9179 140.4262 5.9 2016
23410 12/29/2016 -9.0283 118.6639 6.3 2016
23411 12/30/2016 37.3973 141.4103 5.5 2016

23412 rows × 5 columns

df.assign(Year = list(map(lambda x: x.split('/')[-1], df.Date))).Year.unique()
array(['1965', '1966', '1967', '1968', '1969', '1970', '1971', '1972',
       '1973', '1974', '1975', '1975-02-23T02:58:41.000Z', '1976', '1977',
       '1978', '1979', '1980', '1981', '1982', '1983', '1984', '1985',
       '1985-04-28T02:53:41.530Z', '1986', '1987', '1988', '1989', '1990',
       '1991', '1992', '1993', '1994', '1995', '1996', '1997', '1998',
       '1999', '2000', '2001', '2002', '2003', '2004', '2005', '2006',
       '2007', '2008', '2009', '2010', '2011', '2011-03-13T02:23:34.520Z',
       '2012', '2013', '2014', '2015', '2016'], dtype=object)
'1975-02-23T02:58:41.000Z'.split('-')[0]
'1975'
df.assign(Year = list(map(lambda x: x.split('/')[-1], df.Date)))\
.assign(Year = lambda df: list(map(lambda x: x.split('-')[0], df.Year)))
Date Latitude Longitude Magnitude Year
0 01/02/1965 19.2460 145.6160 6.0 1965
1 01/04/1965 1.8630 127.3520 5.8 1965
2 01/05/1965 -20.5790 -173.9720 6.2 1965
3 01/08/1965 -59.0760 -23.5570 5.8 1965
4 01/09/1965 11.9380 126.4270 5.8 1965
... ... ... ... ... ...
23407 12/28/2016 38.3917 -118.8941 5.6 2016
23408 12/28/2016 38.3777 -118.8957 5.5 2016
23409 12/28/2016 36.9179 140.4262 5.9 2016
23410 12/29/2016 -9.0283 118.6639 6.3 2016
23411 12/30/2016 37.3973 141.4103 5.5 2016

23412 rows × 5 columns

df.assign(Year = list(map(lambda x: x.split('/')[-1], df.Date)))\
.assign(Year = lambda df: list(map(lambda x: x.split('-')[0], df.Year))).Year.unique()
array(['1965', '1966', '1967', '1968', '1969', '1970', '1971', '1972',
       '1973', '1974', '1975', '1976', '1977', '1978', '1979', '1980',
       '1981', '1982', '1983', '1984', '1985', '1986', '1987', '1988',
       '1989', '1990', '1991', '1992', '1993', '1994', '1995', '1996',
       '1997', '1998', '1999', '2000', '2001', '2002', '2003', '2004',
       '2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012',
       '2013', '2014', '2015', '2016'], dtype=object)
lst =[ 
    df.assign(Year = list(map(lambda x: x.split('/')[-1], df.Date)))\
    .assign(Year = lambda df: list(map(lambda x: x.split('-')[0] ,df.Year)))\
    .groupby('Year')\
    .pipe(list)[_year][1]\
    .loc[:,['Latitude','Longitude']]\
    .pipe(np.array).tolist()
    
    for _year in range(2016-1965+1) 
]

Step2: folium

m=folium.Map(scrollWheelZoom=False)
folium.plugins.HeatMapWithTime(
    lst,
    radius=5,
    index=list(range(1965,2017)) 
).add_to(m)
m
Make this Notebook Trusted to load map: File -> Trust Notebook

숙제

지진자료에서 1985년 이후의 자료만 고른뒤에 HeatMapWithTime()을 이용하여 시각화하라.

lst =[ 
    df.assign(Year = list(map(lambda x: x.split('/')[-1], df.Date)))\
    .assign(Year = lambda df: list(map(lambda x: x.split('-')[0] ,df.Year)))\
    .groupby('Year')\
    .pipe(list)[_year][1]\
    .loc[:,['Latitude','Longitude']]\
    .pipe(np.array).tolist()
    
    for _year in range(2016-1985+1) 
]
m=folium.Map(scrollWheelZoom=False)
folium.plugins.HeatMapWithTime(
    lst,
    radius=5,
    index=list(range(1985,2017)) 
).add_to(m)
m
Make this Notebook Trusted to load map: File -> Trust Notebook

12주차(2)_1123

import plotly.express as px

px.scatter_geo

세계지도 그리기

px.scatter_geo()
px.scatter_geo(projection='natural earth') #동그랗게

세계지도 + 버블

- 예시1

df = pd.DataFrame({'lat':[37,0], 'lon':[127,0], 'size':[100,5]})
df
lat lon size
0 37 127 100
1 0 0 5
px.scatter_geo(
    data_frame=df,
    lat = 'lat',
    lon = 'lon',
    size = 'size'
)

- 예시2

df= pd.DataFrame({'code':['KOR','JPN'], 'size':[100,30]})
df
code size
0 KOR 100
1 JPN 30
px.scatter_geo(
    data_frame = df,
    locations = 'code',
    size = 'size'
)

Gapminder data 시각화

- Gapminder data: 국가별 기대수명, 1인당 GDP, 인구에 대한 데이터

  • 특징: 연도별로 정리가 되어있다.
df=px.data.gapminder()
df
country continent year lifeExp pop gdpPercap iso_alpha iso_num
0 Afghanistan Asia 1952 28.801 8425333 779.445314 AFG 4
1 Afghanistan Asia 1957 30.332 9240934 820.853030 AFG 4
2 Afghanistan Asia 1962 31.997 10267083 853.100710 AFG 4
3 Afghanistan Asia 1967 34.020 11537966 836.197138 AFG 4
4 Afghanistan Asia 1972 36.088 13079460 739.981106 AFG 4
... ... ... ... ... ... ... ... ...
1699 Zimbabwe Africa 1987 62.351 9216418 706.157306 ZWE 716
1700 Zimbabwe Africa 1992 60.377 10704340 693.420786 ZWE 716
1701 Zimbabwe Africa 1997 46.809 11404948 792.449960 ZWE 716
1702 Zimbabwe Africa 2002 39.989 11926563 672.038623 ZWE 716
1703 Zimbabwe Africa 2007 43.487 12311143 469.709298 ZWE 716

1704 rows × 8 columns

df.query('year==2007')
country continent year lifeExp pop gdpPercap iso_alpha iso_num
11 Afghanistan Asia 2007 43.828 31889923 974.580338 AFG 4
23 Albania Europe 2007 76.423 3600523 5937.029526 ALB 8
35 Algeria Africa 2007 72.301 33333216 6223.367465 DZA 12
47 Angola Africa 2007 42.731 12420476 4797.231267 AGO 24
59 Argentina Americas 2007 75.320 40301927 12779.379640 ARG 32
... ... ... ... ... ... ... ... ...
1655 Vietnam Asia 2007 74.249 85262356 2441.576404 VNM 704
1667 West Bank and Gaza Asia 2007 73.422 4018332 3025.349798 PSE 275
1679 Yemen, Rep. Asia 2007 62.698 22211743 2280.769906 YEM 887
1691 Zambia Africa 2007 42.384 11746035 1271.211593 ZMB 894
1703 Zimbabwe Africa 2007 43.487 12311143 469.709298 ZWE 716

142 rows × 8 columns

px.scatter_geo(
    data_frame = df,
    locations = 'iso_alpha',  
    size = 'pop'
)
px.scatter_geo(
    data_frame = df.query('year==2007'),
    locations = 'iso_alpha',  
    size = 'pop',
    color = 'continent' # 국가
)
  1. x,y 좌표 잡기
  2. 크기
  3. color
  4. 시간

…..

px.scatter_geo + animation

px.scatter_geo(
    data_frame = df,
    locations = 'iso_alpha',  
    size = 'pop',
    color = 'continent',
    animation_frame = 'year'
)
px.scatter_geo(
    data_frame = df,
    projection = 'natural earth',
    locations= 'iso_alpha',
    size='pop',
    color='continent',
    animation_frame='year'
)
  • 코로플레스 맵