Weltkarte mit Matplotlib Basemap Toolkit

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
Benutzeravatar
MagBen
User
Beiträge: 780
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Dienstag 31. Oktober 2017, 13:48

Weltkarte zur Kindersterblichkeit (Tode pro 1000 Geburten)

Bild

Verwendung: https://de.wikipedia.org/wiki/Kinderste ... t_weltweit

Daten: https://data.worldbank.org/indicator/SH ... 6&view=map
Country shapes: http://www.naturalearthdata.com/downloa ... l-vectors/

Code: Alles auswählen

"""
Number of deaths of infants under five years per 1,000 live births for 2016. 
Created with Python and Matplotlib Basemap Toolkit.
"""

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np

from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection
from matplotlib.patches import PathPatch
from matplotlib.colors import LinearSegmentedColormap

#########################################################################################
# read mortality data
data = open("API_SH.DYN.MORT_DS2_en_csv_v2/API_SH.DYN.MORT_DS2_en_csv_v2.csv").readlines()
mortality={}
for line in data[5:]:
    line = line.replace('",','|').replace(",","").replace('"',"").strip().split("|")
    if len(line)<10:
        continue
    try:
        value=float(line[-2])
    except:
        continue
    key = line[1]
    mortality[key]=value

#########################################################################################
# draw empty worldmap
fig = plt.figure(figsize=(18,8.6))
plt.subplots_adjust(left=0.01, bottom=0.01, right=1.12, top=0.99)

m = Basemap(projection='robin',lon_0=0, llcrnrlat=-60,urcrnrlat=85, llcrnrlon=-180, urcrnrlon=180, resolution='l')
m.drawmapboundary()


#########################################################################################
# color country shapes
m.readshapefile('ne_110m_admin_0_countries/ne_110m_admin_0_countries', name='world', drawbounds=True, color='gray')

countries = []
undefined_countries = []
mortList  = []
for info, shape in zip(m.world_info, m.world):
    try:
        mort = mortality[info["ADM0_A3"]]
    except:
        undefined_countries.append(Polygon(np.array(shape), True))
        continue

    countries.append(Polygon(np.array(shape), True))
    mortList.append(mort)
    
mortArray = np.array(mortList)
print mortArray.min(), mortArray.max()
ticks = np.linspace(0, 130,14)

#########################################################################################
# colorbar
cm = LinearSegmentedColormap.from_list("cm", ["#81fcff", "#19ff19", "#e2f000", "#ffaa31", "#ff8e51", "#ff6969", "#8c0000", "#3c0000"])
p = PatchCollection(countries, alpha=0.5,  zorder=3, cmap=cm)
p.set_array(mortArray)
p.set_clim([ticks.min(), ticks.max()])

plt.gca().add_collection(p)
cb = fig.colorbar(p, ticks = ticks, shrink=0.6, pad = 0.02)

#########################################################################################
# set countries without data to lightgray
p2 = PatchCollection(undefined_countries, alpha=0.5,  zorder=3, cmap=LinearSegmentedColormap.from_list("lg", ["lightgray", "lightgray"]))
p2.set_array(np.ones((len(undefined_countries),)))
plt.gca().add_collection(p2)

#########################################################################################
# save and show
filename = "infant-under-five-mortality-worldmap-2016"
plt.savefig(filename + ".svg")
plt.savefig(filename + "-1800px.png", dpi=100)
plt.savefig(filename + "-900px.png",  dpi=50)

plt.show()
a fool with a tool is still a fool, www.magben.de, YouTube
Benutzeravatar
MagBen
User
Beiträge: 780
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Samstag 16. Dezember 2017, 11:09

Exportwert in Millionen Dollar (2016)

Bild

Verwendung https://de.wikipedia.org/wiki/Liste_der ... h_Exporten

Code: Alles auswählen

"""
Amount of exports in millions of dollars per country in 2016, in logarithmic scale. 
"""

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import matplotlib.colors as colors
from matplotlib.colors import LogNorm
import numpy as np

from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection
from matplotlib.patches import PathPatch
from matplotlib.colors import LinearSegmentedColormap

#########################################################################################
# read values from data in wiki-table format
data = "".join(open("Export-wiki.txt").readlines())
data = data.replace("\n", "").replace("{","").replace("}","").replace(".","").replace(",",".").split("|-")[1:]
value={}
for line in data:
    line = line.split("|")
    try:
        val=float(line[3])
    except:
        continue
    key = line[2]
    value[key]=val
    
#########################################################################################
# draw empty worldmap
fig = plt.figure(figsize=(18,8.6))
plt.subplots_adjust(left=0.01, bottom=0.01, right=1.12, top=0.99)

m = Basemap(projection='robin',lon_0=0, llcrnrlat=-60,urcrnrlat=85, llcrnrlon=-180, urcrnrlon=180, resolution='l')
m.drawmapboundary()

#########################################################################################
# color country shapes
m.readshapefile('ne_110m_admin_0_countries/ne_110m_admin_0_countries', name='world', drawbounds=True, color='gray')

countries = []
undefined_countries = []
valueList  = []
for info, shape in zip(m.world_info, m.world):
    try:
        val = value[info["ADM0_A3"]]
    except:
        undefined_countries.append(Polygon(np.array(shape), True))
        continue

    countries.append(Polygon(np.array(shape), True))
    valueList.append(val)
    
valueArray = np.array(valueList)
print valueArray.min(), valueArray.max()

#########################################################################################
# colorbar, modified "gist_rainbow" theme
_gist_rainbow_data = (
        (0.000, (1.00, 1.00, 0.80)),
        #(0.030, (1.00, 0.00, 0.00)),
        (0.215, (1.00, 1.00, 0.00)),
        (0.400, (0.00, 1.00, 0.00)),
        (0.586, (0.00, 1.00, 1.00)),
        (0.770, (0.00, 0.00, 1.00)),
        (0.954, (1.00, 0.00, 1.00)),
        (1.000, (1.00, 0.00, 0.75)))
cm = colors.LinearSegmentedColormap.from_list("cm", _gist_rainbow_data, 256)
p = PatchCollection(countries, alpha=0.5,  zorder=3, cmap=cm, norm=LogNorm(vmin=200, vmax=2e6))
p.set_array(valueArray)

plt.gca().add_collection(p)
cb = fig.colorbar(p, shrink=0.6, pad = 0.02, drawedges=False)
cb.solids.set_edgecolor("face")

#########################################################################################
# set countries without data to lightgray
p2 = PatchCollection(undefined_countries, alpha=0.5,  zorder=3, cmap=LinearSegmentedColormap.from_list("lg", ["lightgray", "lightgray"]))
p2.set_array(np.ones((len(undefined_countries),)))
plt.gca().add_collection(p2)

#########################################################################################
# save and show
filename = "Export-Worldmap-2016"
plt.savefig(filename + ".svg")
plt.savefig(filename + "-1800px.png", dpi=100)
plt.savefig(filename + "-900px.png",  dpi=50)

plt.show()
a fool with a tool is still a fool, www.magben.de, YouTube
Sirius3
User
Beiträge: 8277
Registriert: Sonntag 21. Oktober 2012, 17:20

Samstag 16. Dezember 2017, 12:58

@MagBen: Die Importe könntest Du noch ein bißchen aufräumen. Was für ein seltsames Datenformat hast Du denn da gefunden, das man erst noch so umständlich mit replace bearbeiten muß? Warum nimmst Du nicht die offiziellen csv-Daten? Nackte excepts niemals benutzen. Am besten erst gar nicht in den Fall laufen lassen, dass Du versuchst eine nicht-Zahl zu konvertieren.
Benutzeravatar
MagBen
User
Beiträge: 780
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Samstag 16. Dezember 2017, 15:20

Sirius3 hat geschrieben:Die Importe könntest Du noch ein bißchen aufräumen.
Ja, die Karte wird dadurch aber nicht hübscher. Der Hauptgrund für diesen Post ist, ich würde gerne mit Leuten diskutieren, die Python für Karten benutzen.
Sirius3 hat geschrieben:Was für ein seltsames Datenformat hast Du denn da gefunden, das man erst noch so umständlich mit replace bearbeiten muß?
Quelltext einer Tabelle auf Wikipedia.
Sirius3 hat geschrieben:Warum nimmst Du nicht die offiziellen csv-Daten?
Es gibt Daten aus verschiedenen Quellen, z.B. die von der Weltbank. In deren CSV Datei steht alles mögliche drinn. Der Kollege von Wikipedia, der die Tabelle gemacht hat, hat sich aber schon mal die Mühe gemacht, die wesentlichen Daten rauszufiltern. Darauf aufbauend habe ich dann die Karte gemacht.
Sirius3 hat geschrieben:Am besten erst gar nicht in den Fall laufen lassen, dass Du versuchst eine nicht-Zahl zu konvertieren.
Dann müsste ich ja die Arbeit selbst machen, die Python jetzt für mich macht: alle Zeilen rausfiltern, die nicht meiner Annahme entsprechen.
a fool with a tool is still a fool, www.magben.de, YouTube
__deets__
User
Beiträge: 3308
Registriert: Mittwoch 14. Oktober 2015, 14:29

Samstag 16. Dezember 2017, 15:50

MagBen hat geschrieben:
Sirius3 hat geschrieben:Am besten erst gar nicht in den Fall laufen lassen, dass Du versuchst eine nicht-Zahl zu konvertieren.
Dann müsste ich ja die Arbeit selbst machen, die Python jetzt für mich macht: alle Zeilen rausfiltern, die nicht meiner Annahme entsprechen.
Wenn deine Daten so "verhunzt" sind, ist es schon ok sie zu versuchen zu konvertieren, und wenn's in die Hose geht eben den Fehler abzuhandeln. Aber wichtig bleibt dabei keine nackten excepts zu verwenden. Sondern die spezifischen, also zB ValueError, KeyError oder ggf. IndexError. Denn sonst verschreibst du dich & Python wirft eigentlich einen anderen Fehler wie zB NameError und Co - und du bekommst es nicht mit. Darum gewoehnt man sich das am besten gar nicht erst an, um die Fehlersuche handhabbarer zu machen.
Benutzeravatar
MagBen
User
Beiträge: 780
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Samstag 16. Dezember 2017, 19:54

__deets__ hat geschrieben:Wenn deine Daten so "verhunzt" sind, ist es schon ok sie zu versuchen zu konvertieren
Ich arbeite oft mit Daten, die zu 99% regelmäßig sind, das ist für mich noch nicht verhunzt.
__deets__ hat geschrieben:Aber wichtig bleibt dabei keine nackten excepts zu verwenden. Sondern die spezifischen, also zB ValueError, KeyError oder ggf. IndexError.
Ich werde mich bessern und mir diese Namen merken.
a fool with a tool is still a fool, www.magben.de, YouTube
Antworten