import vincent
world_countries = r'world-countries.json'world = vincent.Map(width=1200, height=1000)
world.geo_data(projection='winkel3', scale=200, world=world_countries)
world.to_json(path)python
當我開始建造Vincent時, 個人一個目的就是使得地圖的建造儘量合理化. 有一些很棒的python地圖庫-參見Basemap 和 Kartograph能讓地圖更有意思. 我強烈推薦這兩個工具, 由於他們都很好用並且很強大. 我想有更簡單一些的工具,能依靠Vega的力量而且容許簡單的語法點到geoJSON文件,詳細描述一個投影和大小/比列,最後輸出地圖.json
例如, 將地圖數據分層來創建更復雜的地圖:框架
vis = vincent.Map(width=1000, height=800)#Add the US county data and a new line colorvis.geo_data(projection='albersUsa', scale=1000, counties=county_geo)
vis + ('2B4ECF', 'marks', 0, 'properties', 'enter', 'stroke', 'value')#Add the state data, remove the fill, write Vega spec output to JSONvis.geo_data(states=state_geo)
vis - ('fill', 'marks', 1, 'properties', 'enter')
vis.to_json(path)工具
加之,等值線地圖需綁定Pandas數據,須要數據列直接映射到地圖要素.假設有一個從geoJSON到列數據的1:1映射,它的語法是很是簡單的:3d
#'merged' is the Pandas DataFramevis = vincent.Map(width=1000, height=800)
vis.tabular_data(merged, columns=['FIPS_Code', 'Unemployment_rate_2011'])
vis.geo_data(projection='albersUsa', scale=1000, bind_data='data.id', counties=county_geo)
vis + (["#f5f5f5","#000045"], 'scales', 0, 'range')rest
咱們的數據並不是沒有爭議無需改造——用戶須要確保 geoJSON 鍵與熊貓數據框架之間具備1:1的映射。下面就是以前實例所需的簡明的數據框架映射:咱們的國家信息是一個列有FIPS 碼、國家名稱、以及經濟信息(列名省略)的 CSV 文件:code
00000,US,United States,154505871,140674478,13831393,9,50502,10001000,AL,Alabama,2190519,1993977,196542,9,41427,10001001,AL,Autauga County,25930,23854,2076,8,48863,117.901003,AL,Baldwin County,85407,78491,6916,8.1,50144,12101005,AL,Barbour County,9761,8651,1110,11.4,30117,72.7orm
在 geoJSON 中,咱們的國家形狀是以 FIPS 碼爲id 的(感謝 fork 自 Trifacta 的相關信息)。爲了簡便,實際形狀已經作了簡略,在示例數據能夠找到完整的數據集:blog
{"type":"FeatureCollection","features":[
{"type":"Feature","id":"1001","properties":{"name":"Autauga"}
{"type":"Feature","id":"1003","properties":{"name":"Baldwin"}
{"type":"Feature","id":"1005","properties":{"name":"Barbour"}
{"type":"Feature","id":"1007","properties":{"name":"Bibb"}
{"type":"Feature","id":"1009","properties":{"name":"Blount"}
{"type":"Feature","id":"1011","properties":{"name":"Bullock"}
{"type":"Feature","id":"1013","properties":{"name":"Butler"}
{"type":"Feature","id":"1015","properties":{"name":"Calhoun"}
{"type":"Feature","id":"1017","properties":{"name":"Chambers"}
{"type":"Feature","id":"1019","properties":{"name":"Cherokee"}rem
咱們須要匹配 FIPS 碼,確保匹配正確,不然 Vega 沒法正確的壓縮數據:
import jsonimport pandas as pd#Map the county codes we have in our geometry to those in the#county_data file, which contains additional rows we don't needwith open(county_geo, 'r') as f:
get_id = json.load(f)#Grab the FIPS codes and load them into a dataframecounty_codes = [x['id'] for x in get_id['features']]
county_df = pd.DataFrame({'FIPS_Code': county_codes}, dtype=str)#Read into Dataframe, cast to string for consistencydf = pd.read_csv(county_data, na_values=[' '])
df['FIPS_Code'] = df['FIPS_Code'].astype(str)#Perform an inner join, pad NA's with data from nearest countymerged = pd.merge(df, county_df, on='FIPS_Code', how='inner')
merged = merged.fillna(method='pad')
>>>merged.head()
FIPS_Code State Area_name Civilian_labor_force_2011 Employed_2011 \ 0 1001 AL Autauga County 25930 23854
1 1003 AL Baldwin County 85407 78491
2 1005 AL Barbour County 9761 8651
3 1007 AL Bibb County 9216 8303
4 1009 AL Blount County 26347 24156
Unemployed_2011 Unemployment_rate_2011 Median_Household_Income_2011 \0 2076 8.0 48863 1 6916 8.1 50144 2 1110 11.4 30117 3 913 9.9 37347 4 2191 8.3 41940
Med_HH_Income_Percent_of_StateTotal_2011
0 117.9 1 121.0 2 72.7 3 90.2 4 101.2
如今,咱們能夠快速生成不一樣的等值線:
vis.tabular_data(merged, columns=['FIPS_Code', 'Civilian_labor_force_2011'])
這隻能告訴咱們 LA 和 King 面積很是大,人口很是稠密。讓咱們再看看中等家庭收入:
vis.tabular_data(merged, columns=['FIPS_Code', 'Median_Household_Income_2011'])
明顯不少高收入區域在東海岸或是其餘高密度區域。我敢打賭,在城市層級這將更加有趣,但這須要等之後發佈的版本。讓咱們快速重置地圖,再看看國家失業率:
#Swap county data for state data, reset mapstate_data = pd.read_csv(state_unemployment)
vis.tabular_data(state_data, columns=['State', 'Unemployment'])
vis.geo_data(bind_data='data.id', reset=True, states=state_geo)
vis.update_map(scale=1000, projection='albersUsa')
vis + (['#c9cedb', '#0b0d11'], 'scales', 0, 'range')
地圖便是個人激情所在——我但願 Vincent 可以更強,包含輕鬆的添加點、標記及其它的能力。若是各位讀者對於映射方面有什麼功能上的需求,能夠在Github上給我發問題。