老鼠屎地理資訊視覺化第三彈:Plotly+Pyecharts繪製地理座標系線圖
由於最近老鼠屎做的東西和地圖上的線型圖相關,因此在這裡做一點簡單總結。很多地方都除錯得很不理想,希望成功的地方可以給大家帶來一點點啟發,不理想的地方也歡迎大神們賜教。
1 Plotly
1.1 地圖上繪製線
有關pyplot的相關在老鼠屎的博文使用plotly神器繪製地圖(Python版--demo雖易,操作不易,且學且珍惜)中有過簡要介紹,這裡老鼠屎根據自己的需要寫了一個小demo,實戰演練了一下,以及實現了給不同線賦以不同數值,通過透明度予以體現。
#引入相關庫 import pandas as pd from plotly.offline import init_notebook_mode, iplot init_notebook_mode(connected='True') #這裡畫的對應下圖中一個個的點 lonlat = [ dict( type = 'scattergeo', #這個地方可以選擇的只有"ISO-3","USA-states"和"country names" locationmode = 'country names', #我這裡把這些點放在一個叫location的DataFrame裡面,這裡是它們的經緯度資訊 lon = location['lon'], lat = location['lat'], hoverinfo = 'text', text = location['station'], mode = 'markers', marker = dict( size=2, color='rgb(255, 0, 0)', line = dict( width=3, color='rgba(68, 68, 68, 0)' ) ))] #這裡標明路徑資訊,我把路徑資訊放在一個叫hjnm2的DataFrame裡面 subway_paths = [] for i in range( len(hjnm2) ): subway_paths.append( dict( type = 'scattergeo', locationmode = 'country names', lon = [ hjnm2['lon_x'][i], hjnm2['lon_y'][i] ], lat = [ hjnm2['lat_x'][i], hjnm2['lat_y'][i] ], mode = 'lines', line = dict( width = 1, color = 'red', ), #這裡很有趣,用線的透明度來表示數量的多少 opacity = float(hjnm2['nums'][i])/float(hjnm2['nums'].max()), ) ) layout = dict( title = 'XXXXXXXX', showlegend = False, geo = dict( #設定地圖的範圍,可以選擇的有"world","usa","europe","asia","africa", #"north america"和"south america" scope='asia', #projection=dict( type='azimuthal equal area' ), showland = True, landcolor = 'rgb(243, 243, 243)', countrycolor = 'rgb(204, 204, 204)', ), ) fig = dict( data=subway_paths + lonlat, layout=layout ) iplot( fig, filename='d3-flight-paths' )
來看一下效果。由於我的DataFrame比較大,有70000多條資料,使用plotly真的載入不出來。這裡先用20000條資料先跑起來看了一下。
由於scope選擇的是"asia",而我繪製的區域很小,因而在地圖上看著就是一個點,放大後如下圖所示。
我的location資料格式大體如下:
hjnm2資料格式如下:
1.2 呼叫mapbox
import plotly.plotly as py import plotly.graph_objs as go import plotly.graph_objs as go from plotly.offline import init_notebook_mode, iplot init_notebook_mode(connected='True') mapbox_access_token = 'XXXXXXXX' data = [ go.Scattermapbox( lat=['38.91427','38.91538','38.91458', '38.92239','38.93222','38.90842', '38.91931','38.93260','38.91368', '38.88516','38.921894','38.93206', '38.91275'], lon=['-77.02827','-77.02013','-77.03155', '-77.04227','-77.02854','-77.02419', '-77.02518','-77.03304','-77.04509', '-76.99656','-77.042438','-77.02821', '-77.01239'], mode='lines', marker=dict( size=9 ), text=["The coffee bar","Bistro Bohem","Black Cat", "Snap","Columbia Heights Coffee","Azi's Cafe", "Blind Dog Cafe","Le Caprice","Filter", "Peregrine","Tryst","The Coupe", "Big Bear Cafe"], ) ] layout = go.Layout( autosize=True, hovermode='closest', mapbox=dict( accesstoken=mapbox_access_token, bearing=0, center=dict( lat=38.92, lon=-77.07 ), pitch=0, zoom=10 ), ) fig = dict(data=data, layout=layout) iplot(fig, filename='Multiple Mapbox')
和剛剛的效果相比,呼叫mapbox在地圖的顯示上更加細緻準確了,然而這種方法是對相連的這些點依次連線,並沒有實現start-end這種想要的效果。當然,這裡特別強調,這裡有可能是博主功力問題沒能夠實現那種效果,博主歡迎大神賜教,不勝感激!
2 Pyecharts
2.1 安裝
pyecharts的安裝非常簡單,就普通的pip install就可以。對於普通的圖表,如bar,line等,安裝好後即可製圖。然而對於地圖,如果僅僅是安裝了pyecharts這個庫,程式碼執行後會發現結果並無法顯示。這裡有個很重要的坑,在pyecharts中需要安裝地圖相關庫才可以,當然安裝的方法也是在cmd中pip install即可。安裝好後需要重啟一下jupyter notebook。
pip install echarts-countries-pypkg
pip install echarts-china-provinces-pypkg
pip install echarts-china-cities-pypkg
pip install echarts-china-counties-pypkg
pip install echarts-china-misc-pypkg
pip install echarts-united-kingdom-pypkg
2.2 使用pyecharts繪製地理座標系線圖
有關使用pyecharts繪製地理座標系線圖,在pyecharts官方文件中有介紹,然而其官方文件的demo是某一已有地點到另一已有地點的連線,這裡主要是將地點自定義。
繪製地理座標系線圖,使用GeoLines方法,在其引數geo_cities_coords中傳入一個dict,用於自定義地區經緯度,類似如 {'阿城': [126.58, 45.32],} 這樣的字典。
from pyecharts import GeoLines, Style
#這裡先經度後緯度,定義各個點座標
geo_cities_coords={'三林': [121.5123244, 31.143310800000002],
'三林東': [121.5232337, 31.14652508],
'三門路': [121.50799520000001, 31.31309147],
'上南路': [121.5064128, 31.14911246],
'上大路': [121.40917900000001, 31.31352358],
'上海體育場': [121.44371310000001, 31.18552163],
'上海體育館': [121.4370549, 31.18272248],
'上海兒童醫學中心': [121.5239264, 31.20405048]}
style = Style(
title_top="#fff",
title_pos = "center",
width=1200,
height=600,
background_color="#404a59"
)
dataline=[["三林","上海兒童醫學中心"],
["三林東","上海體育館"],
["三門路","上海體育場"],
["上南路","上大路"]]
geolines = GeoLines("GeoLines 示例", **style.init_style)
geolines.add("", dataline, is_legend_show=False,maptype = '上海',geo_cities_coords=geo_cities_coords)
geolines.render()
geolines
可以看一下效果。
然而使用pyecharts並沒有實現不同數值通過線條透明度予以體現的功能,以及自定義的地點如何設定顏色仍在探索,
參考資料: