We'd love to have your feedback on some of the data or the general process of this calculator! Please write to carbon@dotconferences.com :)
All emissions are in CO2-equivalent kilograms.
CONFERENCE = "dotswift-2019" # dotjs-2018
# List of different modes of transport and their CO2e emissions per passenger per km
TRANSPORTS = {
# https://www.oui.sncf/aide/calcul-des-emissions-de-co2-sur-votre-trajet-en-train
"train_fr_tgv": {
"km": 0.0032
},
"train_fr_ter": {
"km": 0.0292
},
"train_fr_eurostar": {
"km": 0.0112
},
"train_fr_thalys": {
"km": 0.0116
},
"train_fr_ratp": {
"km": 0.0038
},
"bus_fr_ouibus": {
"km": 0.0228
},
"bus_fr_ratp": {
"km": 0.0947
},
"car_fr": {
"km": 0.205
},
"plane_fr_national": {
"km": 0.168
},
# https://eco-calculateur.dta.aviation-civile.gouv.fr/autres-trajets
# TODO
# https://assets.publishing.service.gov.uk/government/uploads/system/uploads/attachment_data/file/726911/2018_methodology_paper_FINAL_v01-00.pdf
# Table 39
"plane_uk_national": {
"km": 0.1461
},
"plane_uk_europe": {
"km": 0.0895
},
"plane_uk_international": {
"km": 0.1041
}
}
from geopy.geocoders import Nominatim
from geopy.distance import geodesic
import percache
import time
cache = percache.Cache("./geocode.cache")
geolocator = Nominatim(user_agent="carbon-footprint-estimator")
@cache
def geocode(location):
time.sleep(1) # simple rate limit
return geolocator.geocode(location, addressdetails=True)
def coords(location):
geo = geocode(location)
if not geo:
return None
return (geo.latitude, geo.longitude)
def country(location):
geo = geocode(location)
if not geo:
print "*ERROR: could not geocode: %s" % location
return ""
return geo.raw["address"]["country_code"]
def distance(p1, p2):
if not p1 or not p2:
return 0
d = geodesic(p1, p2)
return d.km
def footprint_transport(location1, location2, transport="guess"):
km = distance(coords(location1), coords(location2))
if km == 0:
return 0
if transport == "guess":
transport = guess_transport(location1, location2)
ghg = TRANSPORTS[transport]["km"] * km
return ghg
def guess_transport(location1, location2):
# Guess the most likely form of transport, with some default assumptions
# based on travel to Paris
c1 = country(location1)
c2 = country(location2)
km = distance(coords(location1), coords(location2))
if km == 0 or not c1 or not c2:
return ""
if {c1, c2} in ({"fr"}, {"fr", "lu"}, {"fr", "ch"}):
if km > 100:
return "train_fr_tgv"
else:
return "train_fr_ter"
if {c1, c2} == {"fr", "gb"}:
if "london" in location1.lower()+location2.lower():
return "train_fr_eurostar"
else:
return "plane_uk_europe"
if {c1, c2} in ({"fr", "be"}, {"fr", "nl"}):
return "train_fr_thalys"
# International travel
if len({c1, c2}) == 2:
if km < 3500:
return "plane_uk_europe" # TODO plane_fr_europe
else:
return "plane_uk_international"
raise Exception("%s => %s : Not supported" % (location1, location2))
from IPython.display import HTML, display
import tabulate
def display_table(data):
display(HTML(tabulate.tabulate(data, tablefmt='html')))
# Test transports to Paris
origins = ["Versailles", "Lille", "Metz", "Bordeaux", "Amsterdam", "London", "Glasgow", "Berlin", "Madrid", "NYC", "Honolulu", "Sydney"]
display_table([o, guess_transport(o, "Paris"), footprint_transport(o, "Paris")] for o in origins)
Versailles | train_fr_ter | 0.511848 |
Lille | train_fr_tgv | 0.652776 |
Metz | train_fr_tgv | 0.900583 |
Bordeaux | train_fr_tgv | 1.59728 |
Amsterdam | train_fr_thalys | 4.99701 |
London | train_fr_eurostar | 3.85149 |
Glasgow | plane_uk_europe | 80.4559 |
Berlin | plane_uk_europe | 78.6352 |
Madrid | plane_uk_europe | 94.2384 |
NYC | plane_uk_international | 609.028 |
Honolulu | plane_uk_international | 1247.87 |
Sydney | plane_uk_international | 1765.23 |
from collections import Counter
import re
origins = []
countries = Counter()
cities = Counter()
import csv
FILE = "%s-attendee-cities.csv" % CONFERENCE
# CSV file includes speakers
with open(FILE, "r") as f:
reader = csv.reader(f, delimiter=',', quotechar='"')
for row in reader:
if row[1] == "FR" and not row[0]:
row[0] = "Paris"
row[0] = re.sub("\bcedex\b", "", row[0], flags=re.I)
origins.append("%s, %s" % (row[0], row[1]))
countries[row[1]] += 1
cities[row[0]] += 1
print("Imported %s attendee origin cities" % len(origins))
print("Top countries:")
display_table(countries.most_common(20))
print("Top cities:")
display_table(cities.most_common(20))
Imported 589 attendee origin cities Top countries:
FR | 418 |
GB | 55 |
DE | 19 |
NL | 17 |
BE | 13 |
US | 12 |
RO | 9 |
ES | 7 |
SE | 5 |
PT | 4 |
LT | 4 |
PL | 4 |
BG | 2 |
HR | 2 |
RU | 2 |
RS | 2 |
LU | 2 |
UK | 2 |
MK | 1 |
BY | 1 |
Top cities:
Paris | 259 |
London | 39 |
PARIS | 13 |
Boulogne Billancourt | 12 |
Levallois-Perret | 11 |
Lyon | 10 |
Cluj-Napoca | 7 |
Romainville | 6 |
Amsterdam | 6 |
Rotterdam | 5 |
BOULOGNE-BILLANCOURT | 5 |
4 | |
Stockholm | 4 |
Villeurbanne | 3 |
Hasselt | 3 |
Berlin | 3 |
Villerbanne | 3 |
Kaunas | 3 |
Cranleigh | 3 |
Bordeaux | 3 |
display_table([repr(o), guess_transport(o, "Paris"), footprint_transport(o, "Paris")] for o in origins)
*ERROR: could not geocode: Thibaud David, FR *ERROR: could not geocode: Paris CEDEX, FR *ERROR: could not geocode: Paris CEDEX, FR *ERROR: could not geocode: Auirbeau sur Siagne, FR *ERROR: could not geocode: HRoa, NO *ERROR: could not geocode: Nognet Sur Marne, FR *ERROR: could not geocode: Fontenay-Aix Roses, FR
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Antibes, FR' | train_fr_tgv | 2.21202 |
'Asni\xc3\xa8res-sur-Seine, FR' | train_fr_ter | 0.2205 |
'Romainville, FR' | train_fr_ter | 0.203255 |
'Romainville, FR' | train_fr_ter | 0.203255 |
'Romainville, FR' | train_fr_ter | 0.203255 |
'NANTES, FR' | train_fr_tgv | 1.099 |
'PARIS, FR' | 0 | |
'Noyal sur Vilaine, FR' | train_fr_tgv | 0.953833 |
'Paris, FR' | 0 | |
'NANTES, FR' | train_fr_tgv | 1.099 |
'Bordeaux, FR' | train_fr_tgv | 1.59728 |
'LILLE, FR' | train_fr_tgv | 0.652776 |
'LILLE, FR' | train_fr_tgv | 0.652776 |
'Rennes, FR' | train_fr_tgv | 0.98974 |
'PARIS, FR' | 0 | |
'Rennes, FR' | train_fr_tgv | 0.98974 |
'Sutton, GB' | plane_uk_europe | 29.6815 |
'Thibaud David, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Lyon, FR' | train_fr_tgv | 1.25509 |
'VOISINS-LE-BRETONNEUX, FR' | train_fr_ter | 0.718687 |
'Toulouse, FR' | train_fr_tgv | 1.88152 |
'Villate, FR' | train_fr_tgv | 1.93132 |
'Vancouver, CA' | plane_uk_international | 827.197 |
'Lyon, FR' | train_fr_tgv | 1.25509 |
'Torrevieja, ES' | plane_uk_europe | 110.365 |
'Porto, PT' | plane_uk_europe | 108.696 |
'Chissay-en-Touraine, FR' | train_fr_tgv | 0.61388 |
'Draveil, FR' | train_fr_ter | 0.569978 |
'Paris, FR' | 0 | |
'Cork, IE' | plane_uk_europe | 75.1619 |
'LONDON, GB' | train_fr_eurostar | 3.85149 |
'Paris, FR' | 0 | |
'London, GB' | train_fr_eurostar | 3.85149 |
'le Rouret, FR' | train_fr_tgv | 2.17074 |
'Francheville, FR' | train_fr_tgv | 0.353588 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Noisy le Sec, FR' | train_fr_ter | 0.239956 |
'Barcelona, ES' | plane_uk_europe | 74.3474 |
'Lyon, FR' | train_fr_tgv | 1.25509 |
'Lyon, FR' | train_fr_tgv | 1.25509 |
'LYON, FR' | train_fr_tgv | 1.25509 |
'Lyon, FR' | train_fr_tgv | 1.25509 |
'Darmstadt, DE' | plane_uk_europe | 42.1702 |
'SAINT-DREZERY, FR' | train_fr_tgv | 1.86648 |
'Haguenau, FR' | train_fr_tgv | 1.27705 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Athens, CY' | plane_uk_europe | 267.626 |
'Fontvielle, FR' | train_fr_tgv | 1.52145 |
'Paris, FR' | 0 | |
'ST SEBASTIEN SUR LOIRE, FR' | train_fr_tgv | 1.09092 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Munich, DE' | plane_uk_europe | 61.3923 |
'Nottingham, GB' | plane_uk_europe | 46.3499 |
'Nottingham, GB' | plane_uk_europe | 46.3499 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Amsterdam, NL' | train_fr_thalys | 4.99701 |
'Paris, FR' | 0 | |
'BEYNES, FR' | train_fr_tgv | 1.97491 |
'Stuttgart, DE' | plane_uk_europe | 44.8739 |
'Stuttgart, DE' | plane_uk_europe | 44.8739 |
'Dortmund, DE' | plane_uk_europe | 42.0361 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Taurage, LT' | plane_uk_europe | 137.314 |
'Paris, FR' | 0 | |
'Zagreb, HR' | plane_uk_europe | 96.8571 |
'Zagreb, HR' | plane_uk_europe | 96.8571 |
'Chaville, FR' | train_fr_ter | 0.382808 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Bois-Colombes, FR' | train_fr_ter | 0.260969 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Tetovo, MK' | plane_uk_europe | 146.572 |
'PARIS, FR' | 0 | |
'Boulogne Billancourt, FR' | train_fr_ter | 0.24803 |
'Boulogne Billancourt, FR' | train_fr_ter | 0.24803 |
'Boulogne Billancourt, FR' | train_fr_ter | 0.24803 |
'Boulogne Billancourt, FR' | train_fr_ter | 0.24803 |
'Lyon, FR' | train_fr_tgv | 1.25509 |
'London, GB' | train_fr_eurostar | 3.85149 |
'Cesson Sevign\xc3\xa9, FR' | train_fr_tgv | 0.971518 |
'MORDELLES, FR' | train_fr_tgv | 1.03211 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Barcelona, ES' | plane_uk_europe | 74.3474 |
'Barcelona, ES' | plane_uk_europe | 74.3474 |
'Montrouge, FR' | train_fr_ter | 0.156711 |
'Villiers sur Marne, FR' | train_fr_ter | 0.417314 |
'vitry sur seine, FR' | train_fr_ter | 0.240052 |
'CLAMART, FR' | train_fr_ter | 0.263307 |
'Chatillon, FR' | train_fr_ter | 0.227174 |
'Madison, US' | plane_uk_international | 696.658 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Krak\xc3\xb3w, PL' | plane_uk_europe | 114.85 |
'Krak\xc3\xb3w, PL' | plane_uk_europe | 114.85 |
'BEOGRAD, RS' | plane_uk_europe | 129.616 |
'BEOGRAD, RS' | plane_uk_europe | 129.616 |
'Amsterdam, NL' | train_fr_thalys | 4.99701 |
'Rennes, FR' | train_fr_tgv | 0.98974 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'Deerlijk, BE' | train_fr_thalys | 2.69282 |
'Gent, BE' | train_fr_thalys | 3.0567 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Karlsruhe, DE' | plane_uk_europe | 39.705 |
'Differdange, LU' | train_fr_tgv | 0.858323 |
'Differdange, LU' | train_fr_tgv | 0.858323 |
'Livry Gargan, FR' | train_fr_ter | 0.429897 |
'Paris, FR' | 0 | |
'Villerbanne, FR' | train_fr_tgv | 1.25739 |
'Villerbanne, FR' | train_fr_tgv | 1.25739 |
'Villerbanne, FR' | train_fr_tgv | 1.25739 |
'Paris CEDEX, FR' | 0 | |
'Paris CEDEX, FR' | 0 | |
'Zoetermeer, NL' | train_fr_thalys | 4.4947 |
'Hamburg, DE' | plane_uk_europe | 66.815 |
', GB' | plane_uk_europe | 67.7527 |
', GB' | plane_uk_europe | 67.7527 |
', GB' | plane_uk_europe | 67.7527 |
', GB' | plane_uk_europe | 67.7527 |
'London, GB' | train_fr_eurostar | 3.85149 |
'Kidlington, GB' | plane_uk_europe | 37.5438 |
'Antwerpen, BE' | train_fr_thalys | 3.49317 |
'Antwerpen, BE' | train_fr_thalys | 3.49317 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Ingelheim am Rhein, DE' | plane_uk_europe | 38.6641 |
'PARIS, FR' | 0 | |
'PARIS, FR' | 0 | |
'PARIS, FR' | 0 | |
'PARIS, FR' | 0 | |
'St.Petersburg, RU' | plane_uk_europe | 194.174 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Romainville, FR' | train_fr_ter | 0.203255 |
'Romainville, FR' | train_fr_ter | 0.203255 |
'Romainville, FR' | train_fr_ter | 0.203255 |
'Walldorf, DE' | plane_uk_europe | 41.3662 |
'paris, FR' | 0 | |
'paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Warsaw, PL' | plane_uk_europe | 122.637 |
'Lyon, FR' | train_fr_tgv | 1.25509 |
'Levallois-Perret, FR' | train_fr_ter | 0.179809 |
'Caluire et Cuire, FR' | train_fr_tgv | 1.24397 |
'Neuville sur Saone, FR' | train_fr_tgv | 1.21873 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Levallois-Perret, FR' | train_fr_ter | 0.179809 |
'Kaunas, LT' | plane_uk_europe | 145.056 |
'Kaunas, LT' | plane_uk_europe | 145.056 |
'Kaunas, LT' | plane_uk_europe | 145.056 |
'Stockholm, SE' | plane_uk_europe | 138.407 |
'London, GB' | train_fr_eurostar | 3.85149 |
'Auirbeau sur Siagne, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Warsaw, PL' | plane_uk_europe | 122.637 |
'Paris, FR' | 0 | |
'BOULOGNE-BILLANCOURT, FR' | train_fr_ter | 0.24803 |
'BOULOGNE-BILLANCOURT, FR' | train_fr_ter | 0.24803 |
'BOULOGNE-BILLANCOURT, FR' | train_fr_ter | 0.24803 |
'BOULOGNE-BILLANCOURT, FR' | train_fr_ter | 0.24803 |
'BOULOGNE-BILLANCOURT, FR' | train_fr_ter | 0.24803 |
'Saint Mars la Briere, FR' | train_fr_tgv | 0.553288 |
'Issy-Les-Moulineaux, FR' | train_fr_ter | 0.196173 |
'Issy-Les-Moulineaux, FR' | train_fr_ter | 0.196173 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'le Kremlin Bicetre, FR' | train_fr_ter | 0.143432 |
'le Kremlin Bicetre, FR' | train_fr_ter | 0.143432 |
'Chaumont en Vexin, FR' | train_fr_ter | 1.65564 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'Lvovskiy, RU' | plane_uk_europe | 242.774 |
'London, GB' | train_fr_eurostar | 3.85149 |
'Niort, FR' | train_fr_tgv | 1.12736 |
'Paris, FR' | 0 | |
'Waddinxveen, NL' | train_fr_thalys | 4.52481 |
'PARIS, FR' | 0 | |
'PARIS, FR' | 0 | |
'Brugge, BE' | train_fr_thalys | 3.12054 |
'Cluj-Napoca, RO' | plane_uk_europe | 143.389 |
'Cluj-Napoca, RO' | plane_uk_europe | 143.389 |
'Cluj-Napoca, RO' | plane_uk_europe | 143.389 |
'Cluj-Napoca, RO' | plane_uk_europe | 143.389 |
'Cluj-Napoca, RO' | plane_uk_europe | 143.389 |
'Cluj-Napoca, RO' | plane_uk_europe | 143.389 |
'Cluj-Napoca, RO' | plane_uk_europe | 143.389 |
'Lyon, FR' | train_fr_tgv | 1.25509 |
'Lisboa, PT' | plane_uk_europe | 130.22 |
'Lisboa, PT' | plane_uk_europe | 130.22 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'Cascais, PT' | plane_uk_europe | 131.287 |
'London, GB' | train_fr_eurostar | 3.85149 |
'Aachen, DE' | plane_uk_europe | 30.7045 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'London, GB' | train_fr_eurostar | 3.85149 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Toulouse, FR' | train_fr_tgv | 1.88152 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'BARCELONA, ES' | plane_uk_europe | 74.3474 |
'Levallois-Perret, FR' | train_fr_ter | 0.179809 |
'Levallois-Perret, FR' | train_fr_ter | 0.179809 |
'Levallois-Perret, FR' | train_fr_ter | 0.179809 |
'Kyiv, UA' | plane_uk_europe | 181.662 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'CASTRIES, FR' | train_fr_tgv | 1.8856 |
'Madrid, ES' | plane_uk_europe | 94.2384 |
'Madrid, ES' | plane_uk_europe | 94.2384 |
'Berlin, DE' | plane_uk_europe | 78.6352 |
'PARIS, FR' | 0 | |
'LIDING\xc3\x96, SE' | plane_uk_europe | 138.904 |
'London, GB' | train_fr_eurostar | 3.85149 |
'Seeheim-Jugenheim, DE' | plane_uk_europe | 41.9049 |
'Amsterdam, NL' | train_fr_thalys | 4.99701 |
'Utrecht, NL' | train_fr_thalys | 4.74653 |
'Utrecht, NL' | train_fr_thalys | 4.74653 |
'Amsterdam, NL' | train_fr_thalys | 4.99701 |
'Amsterdam, NL' | train_fr_thalys | 4.99701 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Aachen, DE' | plane_uk_europe | 30.7045 |
'HRoa, NO' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Chatou, FR' | train_fr_ter | 0.429495 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Bordeaux, FR' | train_fr_tgv | 1.59728 |
'Bordeaux, FR' | train_fr_tgv | 1.59728 |
'Saint Gilles, BE' | train_fr_thalys | 3.03782 |
'Brussels, BE' | train_fr_thalys | 3.0618 |
'CESSON SEVIGNE, FR' | train_fr_tgv | 0.971518 |
'Montferrier sur Lez, FR' | train_fr_tgv | 1.88321 |
'D\xc3\xbcren, DE' | plane_uk_europe | 32.9002 |
'Deerlijk, BE' | train_fr_thalys | 2.69282 |
'Boulogne-Billancourt, FR' | train_fr_ter | 0.24803 |
'K\xc3\xb6ln, DE' | plane_uk_europe | 36.1507 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Milano, IT' | plane_uk_europe | 57.3372 |
'Boulogne Billancourt, FR' | train_fr_ter | 0.24803 |
'Boulogne Billancourt, FR' | train_fr_ter | 0.24803 |
'Velizy, FR' | train_fr_ter | 0.47148 |
'Seoul, KR' | plane_uk_international | 935.703 |
'PARIS, FR' | 0 | |
'Rotterdam, NL' | train_fr_thalys | 4.33682 |
'Didcot, GB' | plane_uk_europe | 35.7265 |
'75010, FR' | train_fr_ter | 0.0691554 |
'ISSY LES MOULINEAUX, FR' | train_fr_ter | 0.196173 |
'Ris-Orangis, FR' | train_fr_ter | 0.672337 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Toledo, US' | plane_uk_international | 668.282 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Hamburg, DE' | plane_uk_europe | 66.815 |
'Vienna, AT' | plane_uk_europe | 92.7702 |
'Hasselt, BE' | train_fr_thalys | 3.65381 |
'Hasselt, BE' | train_fr_thalys | 3.65381 |
'Hasselt, BE' | train_fr_thalys | 3.65381 |
'Clichy, FR' | train_fr_ter | 0.178898 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Nognet Sur Marne, FR' | 0 | |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'London, GB' | train_fr_eurostar | 3.85149 |
'PALAISEAU, FR' | train_fr_ter | 0.5147 |
'PALAISEAU, FR' | train_fr_ter | 0.5147 |
'75020, FR' | train_fr_ter | 0.123772 |
'London, GB' | train_fr_eurostar | 3.85149 |
'New Rochelle, US' | plane_uk_international | 606.346 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Chissay en Touraine, FR' | train_fr_tgv | 0.61388 |
'PARIS, FR' | 0 | |
'Paris, FR' | 0 | |
'Levallois-Perret, FR' | train_fr_ter | 0.179809 |
'Levallois-Perret, FR' | train_fr_ter | 0.179809 |
'Levallois-Perret, FR' | train_fr_ter | 0.179809 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Sharnbrook, GB' | plane_uk_europe | 38.2435 |
'Sofia, BG' | plane_uk_europe | 157.648 |
'Paris, FR' | 0 | |
'Manchester, GB' | plane_uk_europe | 54.2581 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Lab\xc3\xa8ge, FR' | train_fr_tgv | 1.90571 |
'Lab\xc3\xa8ge, FR' | train_fr_tgv | 1.90571 |
'Toulouse, FR' | train_fr_tgv | 1.88152 |
'London, GB' | train_fr_eurostar | 3.85149 |
'Levallois-Perret, FR' | train_fr_ter | 0.179809 |
'Levallois-Perret, FR' | train_fr_ter | 0.179809 |
'Levallois-Perret, FR' | train_fr_ter | 0.179809 |
'Lannion, FR' | train_fr_tgv | 1.36645 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Chatillon, FR' | train_fr_ter | 0.227174 |
'Herentals, BE' | train_fr_thalys | 3.64518 |
'Bucuresti, RO' | plane_uk_europe | 167.807 |
'Bucuresti, RO' | plane_uk_europe | 167.807 |
'Villeurbanne, FR' | train_fr_tgv | 1.25663 |
'Villeurbanne, FR' | train_fr_tgv | 1.25663 |
'Villeurbanne, FR' | train_fr_tgv | 1.25663 |
'75009 - PARIS 09, FR' | train_fr_ter | 0.0545581 |
'75009 - PARIS 09, FR' | train_fr_ter | 0.0545581 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Heino, NL' | train_fr_thalys | 5.62241 |
'Amsterdam, NL' | train_fr_thalys | 4.99701 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Berlin, DE' | plane_uk_europe | 78.6352 |
'Berlin, DE' | plane_uk_europe | 78.6352 |
'Minsk, BY' | plane_uk_europe | 163.915 |
'Rotterdam, NL' | train_fr_thalys | 4.33682 |
'Rotterdam, NL' | train_fr_thalys | 4.33682 |
'Rotterdam, NL' | train_fr_thalys | 4.33682 |
'Dortmund, DE' | plane_uk_europe | 42.0361 |
'Antony, FR' | train_fr_ter | 0.35523 |
'Hergenrath, BE' | train_fr_thalys | 3.89345 |
'Boulogne Billancourt, FR' | train_fr_ter | 0.24803 |
'Paris, FR' | 0 | |
'Bussy St Georges, FR' | train_fr_ter | 0.742557 |
'Paris, FR' | 0 | |
'Amstelveen, NL' | train_fr_thalys | 4.87877 |
'Sofia, BG' | plane_uk_europe | 157.648 |
'Paris, FR' | 0 | |
'LOOS, FR' | train_fr_tgv | 0.642346 |
'LOOS, FR' | train_fr_tgv | 0.642346 |
'Paris-la-D\xc3\xa9fense, FR' | train_fr_ter | 0.259118 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'San Francisco, US' | plane_uk_international | 934.373 |
'75008, FR' | train_fr_ter | 0.0993955 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Stockholm, SE' | plane_uk_europe | 138.407 |
'Stockholm, SE' | plane_uk_europe | 138.407 |
'Stockholm, SE' | plane_uk_europe | 138.407 |
'flushing, US' | plane_uk_international | 660.541 |
'Lyon, FR' | train_fr_tgv | 1.25509 |
'Lyon, FR' | train_fr_tgv | 1.25509 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Fontenay-Aix Roses, FR' | 0 | |
'Vernouillet, FR' | train_fr_ter | 0.873694 |
'Vernouillet, FR' | train_fr_ter | 0.873694 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'London, GB' | train_fr_eurostar | 3.85149 |
'Guildford, GB' | plane_uk_europe | 30.1674 |
'Boulogne Billancourt, FR' | train_fr_ter | 0.24803 |
'Boulogne Billancourt, FR' | train_fr_ter | 0.24803 |
'Woking, GB' | plane_uk_europe | 30.7908 |
'Woking, GB' | plane_uk_europe | 30.7908 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Puteaux, FR' | train_fr_ter | 0.261301 |
'Puteaux, FR' | train_fr_ter | 0.261301 |
'London, GB' | train_fr_eurostar | 3.85149 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Cleveland, US' | plane_uk_international | 657.208 |
'London, UK' | train_fr_eurostar | 3.85149 |
'Boston, US' | plane_uk_international | 577.384 |
'Pittsburg, US' | plane_uk_international | 653.137 |
'Chicago, US' | plane_uk_international | 694.214 |
'San Jose, US' | plane_uk_international | 935.978 |
'NYC, US' | plane_uk_international | 609.028 |
'Cupertino, US' | plane_uk_international | 936.826 |
'London, UK' | train_fr_eurostar | 3.85149 |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Paris, FR' | 0 | |
'Antony, FR' | train_fr_ter | 0.35523 |
'Paris, FR' | 0 | |
'Cranleigh, GB' | plane_uk_europe | 29.1091 |
'Cranleigh, GB' | plane_uk_europe | 29.1091 |
'Paris, FR' | 0 | |
'Cranleigh, GB' | plane_uk_europe | 29.1091 |
'Levallois, FR' | train_fr_ter | 0.179809 |
'Boulogne Billancourt, FR' | train_fr_ter | 0.24803 |
'Boulogne Billancourt, FR' | train_fr_ter | 0.24803 |
'Boulogne Billancourt, FR' | train_fr_ter | 0.24803 |
'London, GB' | train_fr_eurostar | 3.85149 |
'Chamb\xc3\xa9ry, FR' | train_fr_tgv | 1.45522 |
'PARIS, FR' | 0 | |
'Courbevoie, FR' | train_fr_ter | 0.239817 |
'Marigny L\xe2\x80\x99\xc3\x89glise, FR' | train_fr_tgv | 0.654361 |
'Montreuil, FR' | train_fr_tgv | 0.587976 |
'Paris, FR' | 0 | |
'TASSIN-LA-DEMI-LUNE, FR' | train_fr_tgv | 1.24687 |
'Neuilly sur seine, FR' | train_fr_ter | 0.197775 |
'Boulogne Billancourt, FR' | train_fr_ter | 0.24803 |
'Boulogne Billancourt, FR' | train_fr_ter | 0.24803 |
'Rotterdam, NL' | train_fr_thalys | 4.33682 |
from collections import defaultdict
total_footprint_transport_attendees = sum([
footprint_transport(o, "Paris") * 2 # *2 for return trip
for o in origins
])
total_footprint_by_transport = defaultdict(float)
for o in origins:
t = guess_transport(o, "Paris")
if t:
total_footprint_by_transport[t] += footprint_transport(o, "Paris") * 2
total_distance = sum([
distance(coords(o), coords("Paris")) * 2
for o in origins
])
no_show = 45.0 / len(origins)
total_distance *= (1-no_show)
total_footprint_transport_attendees *= (1-no_show)
print "Total km:", total_distance
print "Total CO2e kg footprint:", total_footprint_transport_attendees
print "Average km/attendee", total_distance / len(origins)
print "Average CO2e kg/attendee:", total_footprint_transport_attendees / len(origins)
print "Total CO2e by transport:"
for k, v in total_footprint_by_transport.items():
print " %s: %s" % (k, v)
*ERROR: could not geocode: Thibaud David, FR *ERROR: could not geocode: Paris CEDEX, FR *ERROR: could not geocode: Paris CEDEX, FR *ERROR: could not geocode: Auirbeau sur Siagne, FR *ERROR: could not geocode: HRoa, NO *ERROR: could not geocode: Nognet Sur Marne, FR *ERROR: could not geocode: Fontenay-Aix Roses, FR Total km: 441935.359549 Total CO2e kg footprint: 34754.8830268 Average km/attendee 750.31470212 Average CO2e kg/attendee: 59.0065925752 Total CO2e by transport: plane_uk_europe: 16086.9525631 train_fr_eurostar: 308.119544801 train_fr_tgv: 155.696439877 train_fr_ter: 45.6523108679 train_fr_thalys: 247.65769123 plane_uk_international: 20785.748845
from bokeh.io import output_notebook, show
from bokeh.plotting import figure
from bokeh.models import (
ColumnDataSource, Circle, LogColorMapper, BasicTicker, ColorBar,
DataRange1d, PanTool, WheelZoomTool, BoxSelectTool
)
from bokeh.models.mappers import ColorMapper, LinearColorMapper
from bokeh.palettes import Viridis5
from bokeh.tile_providers import CARTODBPOSITRON_RETINA
import json, math
import bokeh.tile_providers
output_notebook()
def coords2mercator(coords):
lat, lon = coords
r_major = 6378137.000
x = r_major * math.radians(lon)
scale = x/lon
y = 180.0/math.pi * math.log(math.tan(math.pi/4.0 +
lat * (math.pi/180.0)/2.0)) * scale
return (x, y)
p = figure(x_range=(-16000000, 18000000), y_range=(-4000000, 9000000),
x_axis_type="mercator", y_axis_type="mercator", plot_width=900, plot_height=550)
p.add_tile(CARTODBPOSITRON_RETINA)
unique_coords = Counter()
for o in origins:
if geocode(o):
unique_coords[json.dumps([geocode(o).latitude,geocode(o).longitude])] += 1
source = ColumnDataSource(
data=dict(
lat=[coords2mercator(json.loads(k))[1] for k, v in unique_coords.most_common()],
lon=[coords2mercator(json.loads(k))[0] for k, v in unique_coords.most_common()],
x=[(coords2mercator(json.loads(k))[0], coords2mercator(coords("Paris"))[0]) for k, v in unique_coords.most_common()],
y=[(coords2mercator(json.loads(k))[1], coords2mercator(coords("Paris"))[1]) for k, v in unique_coords.most_common()],
size=[(v*100)**(0.3) for k, v in unique_coords.most_common()],
width=[math.sqrt(v) for k, v in unique_coords.most_common()],
color=["blue" for k, v in unique_coords.most_common()]
)
)
#lines_glyph = p.multi_line('x', 'y', color = 'color', line_width = "width",
# line_alpha = 0.2, hover_line_alpha = 1.0, hover_line_color = 'color',
# source = source)
p.circle(x="lon", y="lat", size="size", fill_color="color", fill_alpha=0.5, line_color=None, source=source)
show(p)
# Commute to the conference
# Compute subway emissions, considering ~90% usage among attendees to get to the conference
split_subway = 0.90
split_car = 0.10
average_distance = 7 # Distance from Chatelet to Docks
subway_co2ekm = 0.0038
total_footprint_subway = len(origins) * 2 * split_subway * average_distance * subway_co2ekm
print "Total subway footprint:", total_footprint_subway
average_distance = 7 # Distance from Chatelet to Docks
subway_co2ekm = 0.205
total_footprint_car = len(origins) * 2 * split_car * average_distance * subway_co2ekm
print "Total car footprint:", total_footprint_car
total_footprint_commute = total_footprint_subway + total_footprint_car
print "Total commute footprint:", total_footprint_commute
Total subway footprint: 28.20132 Total car footprint: 169.043 Total commute footprint: 197.24432
# Other transports
# Food
# Deliveries
total_footprint_transport = total_footprint_transport_attendees + total_footprint_commute
print "Total transport footprint:", total_footprint_transport
Total transport footprint: 34952.1273468
# https://www.consoglobe.com/impact-ecologique-d-une-nuit-d-hotel-cg
one_night_ghg = 6.9
average_stay = 2
# Any attendee with an origin further than this (in km) will be considered as sleeping in a hotel
hotel_km_limit = 100
hotel_attendees = len([
o
for o in origins
if distance(coords(o), coords("Paris")) > hotel_km_limit
])
total_footprint_hotels = hotel_attendees * average_stay * one_night_ghg
print "Total hotel nights:", average_stay * hotel_attendees
print "Total hotel footprint:", total_footprint_hotels
Total hotel nights: 460 Total hotel footprint: 3174.0
docks_surface = 3200
# Watts estimate
heating_kwh = 474 * 24
# https://www.rte-france.com/en/eco2mix/eco2mix-co2-en
kwh_co2e = 0.08
total_heating = heating_kwh * kwh_co2e
# lights, screen, tech
total_other_energy = 0.5 * total_heating # TODO
total_footprint_energy = total_heating + total_other_energy
print "Total energy footprint:", total_footprint_energy
Total energy footprint: 1365.12
attendees = len(origins)
if CONFERENCE == "dotswift-2019": # half-day
kg_per_attendee = 0.2
else:
kg_per_attendee = 0.5
# http://www.greeneatz.com/foods-carbon-footprint.html
# TODO: find better FR source
cheese_ghg = 13.5
# Let's just consider everyone eats only cheese! (among the worst offenders)
total_footprint_food = attendees * kg_per_attendee * cheese_ghg
print "Total food footprint", total_footprint_food
Total food footprint 1590.3
# Badges & print
badges_paper = 0.3
badges_format = 0.075 * 0.120
rollups_surface = 12 * (0.8 * 2) + 6 * (1.6 * 2) + 5 * (2 * 2)
rollups_paper = 0.5
total_paper_kg = (badges_paper * badges_format * len(origins)) + (rollups_surface * rollups_paper)
# https://www.epa.vic.gov.au/~/media/Publications/972.pdf
total_footprint_paper = 2.727 * total_paper_kg
# Stage
total_stage = 0
total_swag = 0
if CONFERENCE == "dotjs-2018":
stage_wood_kg = 4 * 15
stage_cardboard_kg = 26 * 0.5
total_stage = stage_wood_kg + stage_cardboard_kg
# Swag
tshirts = 100 + 450
# https://www.carbontrust.com/media/38358/ctc793-international-carbon-flows-clothing.pdf
total_footprint_tshirts = tshirts * 15
total_swag = total_footprint_tshirts
hoodies = 0
# Cardboard
total_footprint_hardware = total_footprint_paper + total_stage + total_swag
print "Total hardware footprint:", total_footprint_hardware
Total hardware footprint: 83.9651481
total_footprint = total_footprint_transport + total_footprint_hotels + total_footprint_energy + total_footprint_food + total_footprint_hardware
print "Total footprint:", total_footprint
print "Footprint per attendee", total_footprint / len(origins)
Total footprint: 41165.5124949 Footprint per attendee 69.8905135737
from bokeh.palettes import Category10
from bokeh.transform import cumsum
import pandas as pd
from math import pi
raw = {
'Transport': total_footprint_transport,
'Hotels': total_footprint_hotels,
'Energy': total_footprint_energy,
'Food': total_footprint_food,
'Hardware': total_footprint_hardware
}
data = pd.Series(raw).reset_index(name='value').rename(columns={'index':'label'})
data['angle'] = data['value']/data['value'].sum() * 2*pi
data['color'] = Category10[len(raw)]
p = figure(plot_height=350, title="Footprint by category", toolbar_location=None,
tools="hover", tooltips="@label: @value", x_range=(-0.5, 1.0))
p.wedge(x=0, y=1, radius=0.4,
start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
line_color="white", fill_color='color', legend='label', source=dict(data))
p.axis.axis_label=None
p.axis.visible=False
p.grid.grid_line_color = None
show(p)
print raw
{'Food': 1590.3000000000002, 'Hardware': 83.96514810000001, 'Energy': 1365.1200000000001, 'Transport': 34952.12734679976, 'Hotels': 3174.0}