1. 程式人生 > >老鼠屎地理資訊視覺化第三彈:Plotly+Pyecharts繪製地理座標系線圖

老鼠屎地理資訊視覺化第三彈: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並沒有實現不同數值通過線條透明度予以體現的功能,以及自定義的地點如何設定顏色仍在探索, 

參考資料: