2012-11-15 9 views
15

Witam Próbuję wykreślić mapę przy użyciu mapy bazowej pytonów z niektórymi krajami wypełnionymi określonym kolorem.Wypełnij kraje w pythańskiej mapie bazowej

Czy istnieje szybkie i łatwe rozwiązanie?

+2

Może przydatne: http: //www.geophysique. be/2011/01/27/matplotlib-basemap-tutorial-07-shapefiles-unleached/ – unutbu

+0

Uważam, że to pomaga: http://matplotlib.1069221.n5.nabble.com/How-to-draw-a-specific- country-by-basemap-td15744.html –

+2

Dzięki za te komentarze, oni są najbardziej pomocni. Znalazłem też witrynę z bezpłatnymi danymi o krajach, czego właśnie szukałem: http://www.naturalearthdata.com/](http://www.naturalearthdata.com/) –

Odpowiedz

12

Jak już zostało powiedziane przez @unutbu, Thomas 'post here jest dokładnie tym, czego szukasz.

Jeżeli chcesz to zrobić z Cartopy, odpowiedniego kodu (w v0.7) można dostosować od http://scitools.org.uk/cartopy/docs/latest/tutorials/using_the_shapereader.html lekko:

import cartopy.crs as ccrs 
import matplotlib.pyplot as plt 
import cartopy.io.shapereader as shpreader 
import itertools 
import numpy as np 

shapename = 'admin_0_countries' 
countries_shp = shpreader.natural_earth(resolution='110m', 
             category='cultural', name=shapename) 

# some nice "earthy" colors 
earth_colors = np.array([(199, 233, 192), 
           (161, 217, 155), 
           (116, 196, 118), 
           (65, 171, 93), 
           (35, 139, 69), 
           ])/255. 
earth_colors = itertools.cycle(earth_colors) 



ax = plt.axes(projection=ccrs.PlateCarree()) 
for country in shpreader.Reader(countries_shp).records(): 
    print country.attributes['name_long'], earth_colors.next() 
    ax.add_geometries(country.geometry, ccrs.PlateCarree(), 
         facecolor=earth_colors.next(), 
         label=country.attributes['name_long']) 

plt.show() 

output

+3

Należy pamiętać, że powinieneś opublikować najważniejsze części odpowiedzi tutaj, na tej stronie lub usunąć informacje o Twoim wpisie [Zobacz FAQ, gdzie znajdują się odpowiedzi, które są "zaledwie łączem".] (Http: // stackoverflow .com/faq # deletion) Możesz dodać link, jeśli chcesz, ale tylko jako "referencję". Odpowiedź powinna być samodzielna bez potrzeby korzystania z linku. – Taryn

+1

Dzięki @bluefeet - Rozumiem, dlaczego tak się stało. Zaktualizowałem odpowiedź, aby podać nowe informacje (bez powielania oryginalnego linku, do którego nie mam praw autorskich). Pozdrowienia, – pelson

+0

Wywołanie shpreader.natural_earth daje mi błąd http 404, który najwyraźniej próbuje go pobrać? – Leo

9

Zainspirowany odpowiedź od pelson, ja pisać rozwiązanie, które mam. Zostawię to tobie, który działa najlepiej, więc nie przyjmuję w tej chwili żadnej odpowiedzi.

#! /usr/bin/env python 

import sys 
import os 
from pylab import * 
from mpl_toolkits.basemap import Basemap 
import matplotlib as mp 

from shapelib import ShapeFile 
import dbflib 
from matplotlib.collections import LineCollection 
from matplotlib import cm 

def get_shapeData(shp,dbf): 
    for npoly in range(shp.info()[0]): 
    shpsegs = [] 
    shpinfo = [] 

    shp_object = shp.read_object(npoly) 
    verts = shp_object.vertices() 
    rings = len(verts) 
    for ring in range(rings): 
     if ring == 0: 
      shapedict = dbf.read_record(npoly) 
     name = shapedict["name_long"] 
     continent = shapedict["continent"] 
     lons, lats = zip(*verts[ring]) 
     if max(lons) > 721. or min(lons) < -721. or max(lats) > 91. or min(lats) < -91: 
      raise ValueError,msg 
     x, y = m(lons, lats) 
     shpsegs.append(zip(x,y)) 
     shapedict['RINGNUM'] = ring+1 
     shapedict['SHAPENUM'] = npoly+1 
     shpinfo.append(shapedict) 

    lines = LineCollection(shpsegs,antialiaseds=(1,)) 
    lines.set_facecolors(cm.jet(np.random.rand(1))) 
    lines.set_edgecolors('k') 
    lines.set_linewidth(0.3) 
    ax.add_collection(lines) 


if __name__=='__main__': 

    f=figure(figsize=(10,10)) 
    ax = plt.subplot(111) 
    m = Basemap(projection='merc',llcrnrlat=30,urcrnrlat=72,\ 
      llcrnrlon=-40,urcrnrlon=50,resolution='c') 
    m.drawcountries(linewidth=0.1,color='w') 

    sfile = 'ne_10m_admin_0_countries' 

    shp = ShapeFile(sfile) 
    dbf = dbflib.open(sfile) 
    get_shapeData(shp,dbf) 

    show() 
    sys.exit(0) 

Jest to wynik

example for filling in countries in different colours

Oto mój przykład jak wypełnić Albanii w odpowiednim kolorze (nie bardzo elegancki wiem;)).

#HACK for Albania 
    shpsegs = [] 
    shpinfo = [] 

    shp_object = shp.read_object(9) 
    verts = shp_object.vertices() 
    rings = len(verts) 
    for ring in range(rings): 
     if ring == 0: 
      shapedict = dbf.read_record(9) 
     name = shapedict["name_long"] 
     continent = shapedict["continent"] 
     lons, lats = zip(*verts[ring]) 
     if max(lons) > 721. or min(lons) < -721. or max(lats) > 91. or min(lats) < -91: 
      raise ValueError,msg 
     x, y = m(lons, lats) 
     shpsegs.append(zip(x,y)) 
     shapedict['RINGNUM'] = ring+1 
     shapedict['SHAPENUM'] = npoly+1 
     shpinfo.append(shapedict) 
    lines = LineCollection(shpsegs,antialiaseds=(1,)) 
    if name == 'Albania': 
    lines.set_facecolors('w') 
    lines.set_edgecolors('k') 
    lines.set_linewidth(0.3) 
    ax.add_collection(lines) 

Ważne jest, aby zrobić to po wykonaniu wszystkich pozostałych kształtów. Być może uda ci się pozbyć jakiejś części tego kodu, ale jak powiedziałem, było to dla mnie wystarczające.

Dla mojej aplikacji kolorowych contries według nazwy lub kontynentu, dlatego te linie:

name = shapedict["name_long"] 
    continent = shapedict["continent"] 

dane wykorzystane mam z tej strony: http://www.naturalearthdata.com/

+2

Twoja Albania została zatopiona. Niewielu to zauważy: D – theta

+0

Tak, tak samo dzieje się z Armenią. Musiałem do dzieła, poprzez wyraźne wypełnienie tych dwóch krajów później.Zapytanie z ludźmi z naturalearthdata nie było jednoznaczne i nie podążyłem za nimi, kiedy naprawiłem je dla mnie –

+0

@red_tiger Mam ten sam problem z Argentyną i Angolą. Czy możesz umieścić swoje rozwiązanie w "problemie albańskim"? Co powiedzieli ludzie z NaturalEarth? Dzięki. –