Makeover Monday 28/10/2019 World Cities Ranked by Annual Sunshine Hours

2 minute read

Week 44 World Cities Ranked by Annual Sunshine Hours

Data from here

Load packages and import data

import pandas as pd
import altair as alt
df = pd.read_excel('https://query.data.world/s/k5e6ouinen6qpkowpudpowkepydrah')
df.head()
Continent Country City Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Year
0 Africa Ivory Coast Gagnoa 183.0 180.0 196.0 188.0 181.0 118.0 97.0 80.0 110.0 155.0 171.0 164.0 1823.0
1 Africa Ivory Coast Bouaké 242.0 224.0 219.0 194.0 208.0 145.0 104.0 82.0 115.0 170.0 191.0 198.0 2092.0
2 Africa Ivory Coast Abidjan 223.0 223.0 239.0 214.0 205.0 128.0 137.0 125.0 139.0 215.0 224.0 224.0 2296.0
3 Africa Ivory Coast Odienné 242.0 220.2 217.3 214.7 248.8 221.8 183.5 174.5 185.4 235.8 252.0 242.6 2638.6
4 Africa Ivory Coast Ferké 279.0 249.0 253.0 229.0 251.0 221.0 183.0 151.0 173.0 245.0 261.0 262.0 2757.0

So we have a line for each country/city and a column for each month. In ggplot, and probably Altair, it’s not ideal, so I’ll try to create a month column.

df_pivot = df.melt(['Continent', 'Country', 'City', 'Year'], var_name= 'Month', value_name = 'Sunshine')
df_pivot.head()
Continent Country City Year Month Sunshine
0 Africa Ivory Coast Gagnoa 1823.0 Jan 183.0
1 Africa Ivory Coast Bouaké 2092.0 Jan 242.0
2 Africa Ivory Coast Abidjan 2296.0 Jan 223.0
3 Africa Ivory Coast Odienné 2638.6 Jan 242.0
4 Africa Ivory Coast Ferké 2757.0 Jan 279.0

Now creating variables for minimum/maximum monthly sunshine.

#### data frame with max vs min sunshine time
df_plot=df.drop(columns='Year')
df_plot['max_sunshine']=df_plot.loc[:, 'Jan':'Dec'].max(1)
df_plot['min_sunshine']=df_plot.loc[:, 'Jan':'Dec'].min(1)
df_plot.head()
Continent Country City Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec max_sunshine min_sunshine
0 Africa Ivory Coast Gagnoa 183.0 180.0 196.0 188.0 181.0 118.0 97.0 80.0 110.0 155.0 171.0 164.0 196.0 80.0
1 Africa Ivory Coast Bouaké 242.0 224.0 219.0 194.0 208.0 145.0 104.0 82.0 115.0 170.0 191.0 198.0 242.0 82.0
2 Africa Ivory Coast Abidjan 223.0 223.0 239.0 214.0 205.0 128.0 137.0 125.0 139.0 215.0 224.0 224.0 239.0 125.0
3 Africa Ivory Coast Odienné 242.0 220.2 217.3 214.7 248.8 221.8 183.5 174.5 185.4 235.8 252.0 242.6 252.0 174.5
4 Africa Ivory Coast Ferké 279.0 249.0 253.0 229.0 251.0 221.0 183.0 151.0 173.0 245.0 261.0 262.0 279.0 151.0
selection = alt.selection_multi(fields=['Continent'])
color = alt.condition(selection,
                    alt.Color('Continent:N'),
                    alt.value('lightgray'))

base_chart = alt.Chart(df_plot).mark_point().encode(
    y=alt.Y('min_sunshine', title='Minimun monthly sunshine hours'),
    x=alt.X('max_sunshine',scale=alt.Scale(domain=[50, 450]),
            title='Maximum monthly sunshine hours'),
    color=color,
    tooltip=['Country','City']
).add_selection(
    selection
)

df_line = pd.DataFrame({'x': [250], 'y': [150]})
v_line = alt.Chart(df_line).mark_rule(color='black', strokeWidth=1).encode(x='x:Q')
h_line = alt.Chart(df_line).mark_rule(color='black', strokeWidth=1).encode(y='y:Q')

chart = (base_chart+v_line+h_line).configure(
    background='Snow'
).properties(
    title='How does sunshine hours change between the sunniest and least sunny months?',
    width=600,
    height=450
).configure_legend(
    orient='top',
    title=None,
    offset=5
).configure_axis(
    grid=False,
    domain=False,
    titleFontSize=11,
    titleFontWeight='normal',
    titleColor='slategray',
    labelColor='slategray'
).configure_view(
    strokeWidth=1,
    stroke='slategrey'
).configure_title(
    fontSize=15,
    anchor='start',
    color='gray'
)

chart.save("../docs/assets/images/2019_10_28_MM.png")
chart.save('2019_10_28_MM.html')

Static view of the plot as a png:

Static

Interactive view: