At http://www.nomadlist.io is displayed the so called NomadListTM, a ranking list of the best cities to live and work remotely. This ranking is based on NomadScoreTM, a score computed from the monthly cost of living/work, internet speed, weather and level of safety.
NomadCostTM is based on staying in a hostel, hotel or apartment in the center, working in a coworking space and having a basic meal three times a day.
The NomadListTM automatically refreshes once a day.
In this IPython Notebook we visualize the NomadListTM through a plotly bubble chart, based on data displayed today, August 5, 2014.
import pandas as pd
import numpy as np
xl = pd.ExcelFile('NomadList.xls')
df = xl.parse("Sheet1")
df
City | Country | Region | NomadCost | Temperature | InternetSpeed | Pts | Safety | English | |
---|---|---|---|---|---|---|---|---|---|
0 | Chiang May | Thailand | SEAsia | 657 | 29 | 20 | 150 | 5 | 2 |
1 | Taipei | Taiwan | EastAsia | 1100 | 32 | 40 | 83 | 5 | 3 |
2 | Sofia | Bulgaria | Europe | 1527 | 24 | 40 | 56 | 3 | 3 |
3 | Timisoara | Romania | Europe | 2125 | 28 | 60 | 33 | 5 | 4 |
4 | Kosice | Slovakia | Europe | 1503 | 26 | 20 | 30 | 3 | 0 |
5 | Ubud, Bali | Indonesia | SEAsia | 1196 | 29 | 5 | 28 | 5 | 4 |
6 | Penang | Malaysia | SEAsia | 1059 | 29 | 10 | 28 | 3 | 4 |
7 | Belgrade | Serbia | Europe | 1410 | 27 | 10 | 27 | 5 | 4 |
8 | Bangkok | Thailand | SEAsia | 1386 | 32 | 20 | 26 | 5 | 3 |
9 | Wroklav | Poland | Europe | 1840 | 28 | 20 | 25 | 3 | 3 |
10 | Ljubljana | Slovenia | Europe | 2217 | 23 | 20 | 24 | 5 | 5 |
11 | Budapest | Hungary | Europe | 2270 | 27 | 30 | 23 | 3 | 3 |
12 | Lisbon | Portugal | Europe | 2168 | 21 | 40 | 21 | 3 | 4 |
13 | Las Vegas | USA | NorthAmerica | 2148 | 30 | 30 | 16 | 3 | 5 |
14 | Davao | Philippines | SEAsia | 1061 | 31 | 5 | 14 | 5 | 5 |
15 | Montreal | Canada | NorthAmerica | 2334 | 20 | 20 | 9 | 5 | 4 |
16 | Lima | Peru | SouthAmerica | 1121 | 17 | 10 | 7 | 3 | 3 |
17 | Kuala Lumpur | Malaysia | SEAsia | 1199 | 32 | 10 | 6 | 1 | 5 |
18 | Park City | USA | NorthAmerica | 2862 | 25 | 30 | 5 | 5 | 5 |
19 | Orlando | USA | NorthAmerica | 2436 | 27 | 20 | 4 | 5 | 5 |
20 | Singapore | Singapore | SEAsia | 2697 | 33 | 70 | 3 | 5 | 5 |
21 | Santa Monica | USA | NorthAmerica | 2601 | 26 | 30 | 3 | 5 | 5 |
22 | Vancouver | Canada | NorthAmerica | 2879 | 22 | 20 | 2 | 5 | 5 |
23 | Hong Kong | Hong Kong | EastAsia | 2633 | 37 | 90 | 1 | 5 | 5 |
24 | Bordeaux | France | Europe | 3155 | 23 | 30 | 1 | 5 | 2 |
25 | Ho Chi Minh | Vietnam | SEAsia | 1328 | 33 | 20 | 1 | 3 | 2 |
df.columns
Index([u'City', u'Country', u'Region', u'NomadCost', u'Temperature', u'InternetSpeed', u'Pts', u'Safety', u'English'], dtype='object')
L=len(df)
print L
26
import plotly.plotly as py
import plotly.tools as tls
from plotly.graph_objs import *
colors = dict(
EastAsia='rgba(31,119,180, 0.7)',
Europe='rgba(214,39,40, 0.7)',
SEAsia='rgba(44,160,44, 0.7)',
NorthAmerica='rgba(255,127,14, 0.7)',
SouthAmerica='rgba(153,0, 153, 0.7)'
)
sizemode='area'
sizeref=df['Pts'].max()/75
cities=list(df['City'])
countries=list(df['Country'])
Y=list(df['InternetSpeed'])
T=list(df['Temperature'])
livingcost=list(df['NomadCost'])
safety=list(df['Safety'])
sizeb=(df['Pts'].values)*50
m, M= min(livingcost), max(livingcost)
def make_trace(x, y, text, sizeb, color):
return Scatter(
x=x,
y=y,
text=text,
mode='markers',
marker= Marker(
color=color,
size=sizeb, # bubble size
sizeref=sizeref,
sizemode=sizemode,
line= Line(width=1.0) # width of marker border
)
)
text=[]
color=[]
for k in df.index:
txt='Rank '+str(k+1)+': '+ cities[k]+ ' '+'<br>Country:'+ countries[k]+' '\
+'<br>Temperat 08.05.14: '+str(T[k])+'C'+'<br>Safety Level:'+str(safety[k])
text.append(txt)
color.append(colors[df['Region'][k]])
data=Data([make_trace(livingcost,Y, text, sizeb, color)])
ftitle = ' The best cities to live and work remotely,'+\
'<br>based on cost of living, internet speed, weather, and safety'
xtitle = 'Monthly living cost in dollars'
ytitle = 'Internet speed (download) in MBPS'
axis_style = dict(
zeroline=False,
gridcolor='#FFFFFF',
ticks='outside',
ticklen=6,
tickwidth=1
)
anno_txt1='$\\text{Bubble area is proportional to the } \\text{NomadScore}^{\\text{TM}}$'
anno_txt2="Data source: <a href='http://nomadlist.io/'> [1]</a>, August 5, 2014"
layout = Layout(
title=ftitle,
plot_bgcolor='#EFECEA', # set background color to grey
font=Font(family='Raleway, sans-serif'),
hovermode='closest',
showlegend=False,
autosize=False,
width=500,
height=500,
xaxis=XAxis(axis_style,
range=[m-400, M+50],
nticks=18,
tickangle=-45,
title=xtitle
),
yaxis=YAxis(axis_style,
range=[-3, 100],
nticks=11,
title=ytitle
),
margin=Margin(
l=80,
r=80,
b=125,
t=90,
pad=2
),
annotations=Annotations([
Annotation(
showarrow=False,
text=anno_txt1,
xref='paper',
yref='paper',
x=-0.16,
y=-0.3,
xanchor='left',
yanchor='bottom',
font=Font(
size=12
)
),
Annotation(
showarrow=False,
text=anno_txt2,
xref='paper',
yref='paper',
x=-0.16,
y=-0.41,
xanchor='left',
yanchor='bottom',
font=Font(
size=12
)
),
]),
)
fig = Figure(data=data, layout=layout)
py.sign_in('empet', 'my_api_key')
py.iplot(fig, filename='Where-live-workNScore1', width=500, height=500)
from IPython.core.display import HTML
def css_styling():
styles = open("./styles/custom.css", "r").read()
return HTML(styles)
css_styling()