저번 포스팅에 이어, examples
에 있는 plugins
관련된 기능들을 좀 더 살펴보려 한다.
DualMap
This plugin is using the Leaflet plugin Sync by Jieter:
https://github.com/jieter/Leaflet.Sync
The goal is to have two maps side by side. When you pan or zoom on one map, the other will move as well.
import folium
import folium.plugins
The DualMap
class accepts the same arguments as the normal Map
class. Except for these: 'width', 'height', 'left', 'top', 'position'.
In the following example we create a DualMap
, add layer controls and then show the map. Try panning and zooming to check that both maps are syncronized.
m = folium.plugins.DualMap(location=(52.1, 5.1), zoom_start=8)
m
You can access the two submaps with attributes m1
and m2
. You can add objects to each map specifically.
Here we add different tile layers to each map. This way you can see two different tile sets at the same time.
m = folium.plugins.DualMap(location=(52.1, 5.1), tiles=None, zoom_start=8)
folium.TileLayer('openstreetmap').add_to(m.m1)
folium.TileLayer('cartodbpositron').add_to(m.m2)
folium.LayerControl(collapsed=False).add_to(m)
m
Now we're going to add feature groups and markers to both maps and to each map individually. We'll color the shared icon red.
m = folium.plugins.DualMap(location=(52.1, 5.1), tiles='cartodbpositron', zoom_start=8)
fg_both = folium.FeatureGroup(name='markers_both').add_to(m)
fg_1 = folium.FeatureGroup(name='markers_1').add_to(m.m1)
fg_2 = folium.FeatureGroup(name='markers_2').add_to(m.m2)
icon_red = folium.Icon(color='red')
folium.Marker((52.0, 5.0), tooltip='both', icon=icon_red).add_to(fg_both)
folium.Marker((52.4, 5.0), tooltip='1').add_to(fg_1)
folium.Marker((52.0, 5.4), tooltip='2').add_to(fg_2)
folium.LayerControl(collapsed=False).add_to(m)
m
Finally, you can use the layout
argument to change the layout to vertical:
m = folium.plugins.DualMap(layout='vertical')
m
PolyLineOffset
Note : The examples presented below are the copy of the ones presented on https://github.com/bbecquet/Leaflet.PolylineOffset
Basic Demo
- The dashed line is the "model", with no offset applied.
- The Red line is with a -5px offset,
- The Green line is with a 10px offset.
The three are distinct Polyline objects but uses the same coordinate array
from folium import plugins
m = folium.Map(location=[58.0, -11.0], zoom_start=4, tiles="Mapbox Bright")
coords = [
[58.44773, -28.65234],
[53, -23.33496],
[53, -14.32617],
[58.1707, -10.37109],
[59, -13],
[57, -15],
[57, -18],
[60, -18],
[63, -5],
[59, -7],
[58, -3],
[56, -3],
[60, -4],
]
plugins.PolyLineOffset(
coords, weight=2, dash_array="5,10", color="black", opacity=1
).add_to(m)
plugins.PolyLineOffset(coords, color="#f00", opacity=1, offset=-5).add_to(m)
plugins.PolyLineOffset(coords, color="#080", opacity=1, offset=10).add_to(m)
m.save(os.path.join('results', "PolyLineOffset_simple.html"))
m
Bus Lines
A more complex demo.
Offsets are computed automatically depending on the number of bus lines using the same segment.
Other non-offset polylines are used to achieve the white and black outline effect.
m = folium.Map(location=[48.868, 2.365], zoom_start=15)
geojson = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {"lines": [0, 1]},
"geometry": {
"type": "LineString",
"coordinates": [
[2.357919216156006, 48.87621773324153],
[2.357339859008789, 48.874834693731664],
[2.362983226776123, 48.86855408432749],
[2.362382411956787, 48.86796126699168],
[2.3633265495300293, 48.86735432768131],
],
},
},
{
"type": "Feature",
"properties": {"lines": [2, 3]},
"geometry": {
"type": "LineString",
"coordinates": [
[2.351503372192383, 48.86443950493823],
[2.361609935760498, 48.866775611250205],
[2.3633265495300293, 48.86735432768131],
],
},
},
{
"type": "Feature",
"properties": {"lines": [1, 2]},
"geometry": {
"type": "LineString",
"coordinates": [
[2.369627058506012, 48.86619159489603],
[2.3724031448364253, 48.8626397112042],
[2.3728322982788086, 48.8616233285001],
[2.372767925262451, 48.86080456075567],
],
},
},
{
"type": "Feature",
"properties": {"lines": [0]},
"geometry": {
"type": "LineString",
"coordinates": [
[2.3647427558898926, 48.86653565369396],
[2.3647642135620117, 48.86630981023694],
[2.3666739463806152, 48.86314789481612],
[2.3673176765441895, 48.86066339254944],
],
},
},
{
"type": "Feature",
"properties": {"lines": [0, 1, 2, 3]},
"geometry": {
"type": "LineString",
"coordinates": [
[2.3633265495300293, 48.86735432768131],
[2.3647427558898926, 48.86653565369396],
],
},
},
{
"type": "Feature",
"properties": {"lines": [1, 2, 3]},
"geometry": {
"type": "LineString",
"coordinates": [
[2.3647427558898926, 48.86653565369396],
[2.3650002479553223, 48.86660622956524],
[2.365509867668152, 48.866987337550164],
[2.369627058506012, 48.86619159489603],
],
},
},
{
"type": "Feature",
"properties": {"lines": [3]},
"geometry": {
"type": "LineString",
"coordinates": [
[2.369627058506012, 48.86619159489603],
[2.372349500656128, 48.865702850895744],
],
},
},
],
}
# manage overlays in groups to ease superposition order
outlines = folium.FeatureGroup("outlines")
line_bg = folium.FeatureGroup("lineBg")
bus_lines = folium.FeatureGroup("busLines")
bus_stops = folium.FeatureGroup("busStops")
line_weight = 6
line_colors = ["red", "#08f", "#0c0", "#f80"]
stops = []
for line_segment in geojson["features"]:
# Get every bus line coordinates
segment_coords = [[x[1], x[0]] for x in line_segment["geometry"]["coordinates"]]
# Get bus stops coordinates
stops.append(segment_coords[0])
stops.append(segment_coords[-1])
# Get number of bus lines sharing the same coordinates
lines_on_segment = line_segment["properties"]["lines"]
# Width of segment proportional to the number of bus lines
segment_width = len(lines_on_segment) * (line_weight + 1)
# For the white and black outline effect
folium.PolyLine(
segment_coords, color="#000", weight=segment_width + 5, opacity=1
).add_to(outlines)
folium.PolyLine(
segment_coords, color="#fff", weight=segment_width + 3, opacity=1
).add_to(line_bg)
# Draw parallel bus lines with different color and offset
for j, line_number in enumerate(lines_on_segment):
plugins.PolyLineOffset(
segment_coords,
color=line_colors[line_number],
weight=line_weight,
opacity=1,
offset=j * (line_weight + 1) - (segment_width / 2) + ((line_weight + 1) / 2),
).add_to(bus_lines)
# Draw bus stops
for stop in stops:
folium.CircleMarker(
stop,
color="#000",
fill_color="#ccc",
fill_opacity=1,
radius=10,
weight=4,
opacity=1,
).add_to(bus_stops)
outlines.add_to(m)
line_bg.add_to(m)
bus_lines.add_to(m)
bus_stops.add_to(m)
m.save(os.path.join('results', "PolyLineOffset_bus.html"))
m
Mouse Position
from folium.plugins import MousePosition
m = folium.Map()
MousePosition().add_to(m)
m.save(os.path.join('results', 'MousePosition0.html'))
m
m = folium.Map()
# Define a Javascript function that formats the coordinate value
# that is passed to it.
formatter = "function(num) {return L.Util.formatNum(num, 3) + ' º ';};"
MousePosition(
position='topright',
separator=' | ',
empty_string='NaN',
lng_first=True,
num_digits=20,
prefix='Coordinates:',
lat_formatter=formatter,
lng_formatter=formatter
).add_to(m)
m.save(os.path.join('results', 'MousePosition1.html'))
m
Measure Control
from folium.plugins import MeasureControl
m = folium.Map([-27.5717, -48.6256], zoom_start=10)
m.add_child(MeasureControl())
m
Draw
from folium.plugins import Draw
m = folium.Map()
draw = Draw()
draw.add_to(m)
m.save(os.path.join('results', 'Draw0.html'))
m
m = folium.Map(location=[-27.23, -48.36], zoom_start=12)
draw = Draw(export=True)
draw.add_to(m)
m.save(os.path.join('results', 'Draw1.html'))
m
Pattern
import folium
from folium import plugins
m = folium.Map([40., -105.], zoom_start=6)
url = 'https://raw.githubusercontent.com/python-visualization/folium/master/examples/data/us-states.json'
stripes = plugins.pattern.StripePattern(angle=-45)
stripes.add_to(m)
circles = plugins.pattern.CirclePattern(width=20, height=20, radius=5, fill_opacity=0.5, opacity=1)
circles.add_to(m)
def style_function(feature):
default_style = {
'opacity':1.0,
'fillColor': '#ffff00',
'color': 'black',
'weight': 2
}
if feature['properties']['name'] == 'Colorado':
default_style['fillPattern'] = stripes
default_style['fillOpacity'] = 1.0
if feature['properties']['name'] == 'Utah':
default_style['fillPattern'] = circles
default_style['fillOpacity'] = 1.0
return default_style
# Adding remote GeoJSON as additional layer.
folium.GeoJson(url, smooth_factor=0.5, style_function=style_function).add_to(m)
m
출처
'데이터와 함께 탱고를 > 데이터 시각화' 카테고리의 다른 글
이제는 matplotlib 말고, Plotly 를 쓰자. (7) | 2019.08.17 |
---|---|
pandas, bar 그래프(plot) 이쁘게 그리기 (2) | 2019.06.18 |
pyplot 그래프의 범주박스 위치 변경하기 (0) | 2019.06.14 |
folium 의 plugins 패키지 샘플 살펴보기 (7) | 2019.05.25 |
파이썬으로 데이터 시각화하기 1편. matplotlib. (1) | 2019.03.27 |