Today we will make the Hot Spots map from the article Coronavirus Map: Tracking the Global Outbreak that looks like the following - Hot Spots

import altair as alt
import pandas as pd
import geopandas as gpd
alt.renderers.set_embed_options(actions=False)
RendererRegistry.enable('default')
#world = gpd.read_file("https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/ne_10m_admin_0_countries.zip")
world = gpd.read_file("https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/110m/cultural/ne_110m_admin_0_countries.zip")
world.head()
featurecla scalerank LABELRANK SOVEREIGNT SOV_A3 ADM0_DIF LEVEL TYPE ADMIN ADM0_A3 ... NAME_KO NAME_NL NAME_PL NAME_PT NAME_RU NAME_SV NAME_TR NAME_VI NAME_ZH geometry
0 Admin-0 country 1 6 Fiji FJI 0 2 Sovereign country Fiji FJI ... 피지 Fiji Fidżi Fiji Фиджи Fiji Fiji Fiji 斐濟 MULTIPOLYGON (((180.00000 -16.06713, 180.00000...
1 Admin-0 country 1 3 United Republic of Tanzania TZA 0 2 Sovereign country United Republic of Tanzania TZA ... 탄자니아 Tanzania Tanzania Tanzânia Танзания Tanzania Tanzanya Tanzania 坦桑尼亚 POLYGON ((33.90371 -0.95000, 34.07262 -1.05982...
2 Admin-0 country 1 7 Western Sahara SAH 0 2 Indeterminate Western Sahara SAH ... 서사하라 Westelijke Sahara Sahara Zachodnia Saara Ocidental Западная Сахара Västsahara Batı Sahra Tây Sahara 西撒哈拉 POLYGON ((-8.66559 27.65643, -8.66512 27.58948...
3 Admin-0 country 1 2 Canada CAN 0 2 Sovereign country Canada CAN ... 캐나다 Canada Kanada Canadá Канада Kanada Kanada Canada 加拿大 MULTIPOLYGON (((-122.84000 49.00000, -122.9742...
4 Admin-0 country 1 2 United States of America US1 1 2 Country United States of America USA ... 미국 Verenigde Staten van Amerika Stany Zjednoczone Estados Unidos Соединённые Штаты Америки USA Amerika Birleşik Devletleri Hoa Kỳ 美国 MULTIPOLYGON (((-122.84000 49.00000, -120.0000...

5 rows × 95 columns

world = world[['ADMIN', 'NAME', 'ISO_A3', 'CONTINENT', 'geometry']]
world
ADMIN NAME ISO_A3 CONTINENT geometry
0 Fiji Fiji FJI Oceania MULTIPOLYGON (((180.00000 -16.06713, 180.00000...
1 United Republic of Tanzania Tanzania TZA Africa POLYGON ((33.90371 -0.95000, 34.07262 -1.05982...
2 Western Sahara W. Sahara ESH Africa POLYGON ((-8.66559 27.65643, -8.66512 27.58948...
3 Canada Canada CAN North America MULTIPOLYGON (((-122.84000 49.00000, -122.9742...
4 United States of America United States of America USA North America MULTIPOLYGON (((-122.84000 49.00000, -120.0000...
... ... ... ... ... ...
172 Republic of Serbia Serbia SRB Europe POLYGON ((18.82982 45.90887, 18.82984 45.90888...
173 Montenegro Montenegro MNE Europe POLYGON ((20.07070 42.58863, 19.80161 42.50009...
174 Kosovo Kosovo -99 Europe POLYGON ((20.59025 41.85541, 20.52295 42.21787...
175 Trinidad and Tobago Trinidad and Tobago TTO North America POLYGON ((-61.68000 10.76000, -61.10500 10.890...
176 South Sudan S. Sudan SSD Africa POLYGON ((30.83385 3.50917, 29.95350 4.17370, ...

177 rows × 5 columns

world = world[~(world['CONTINENT']=='Antarctica')]
alt.Chart(world).mark_geoshape(stroke='white').encode()
somalia = world[world['NAME'].str.contains('Somali')]
somalia = somalia.dissolve(by='CONTINENT').reset_index()
world=pd.concat([world, somalia])
world.loc[world['ADMIN'].str.contains('eSwatini'), 'ADMIN'] = 'Eswatini'
world.loc[world['ADMIN'].str.contains('Palestine'), 'ADMIN'] = 'West Bank and Gaza'
world.loc[world['ADMIN'].str.contains('Republic of Serbia'), 'ADMIN'] = 'Serbia'
world.loc[world['ADMIN'].str.contains('United Republic of Tanzania'), 'ADMIN'] = 'Tanzania'
world.loc[world['ADMIN'].str.contains('São Tomé and Principe'), 'ADMIN'] = 'Sao Tome and Principe'
world.columns = ['Country_Region', 'NAME', 'iso3', 'CONTINENT', 'geometry']
population_uri = 'https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/UID_ISO_FIPS_LookUp_Table.csv'
population_data = pd.read_csv(population_uri)
population_data = population_data.drop(['UID', 'iso2', 'code3', 'FIPS', 'Admin2', 'Province_State'], axis=1)
population_data = population_data[population_data['Country_Region'] == population_data['Combined_Key']]
population_data = population_data.drop(['Country_Region', 'Combined_Key'], axis=1)

population_data = population_data.reset_index(drop=True)
population_data.head()
iso3 Lat Long_ Population
0 AFG 33.93911 67.709953 38928341.0
1 ALB 41.15330 20.168300 2877800.0
2 DZA 28.03390 1.659600 43851043.0
3 AND 42.50630 1.521800 77265.0
4 AGO -11.20270 17.873900 32866268.0
population_data
iso3 Lat Long_ Population
0 AFG 33.939110 67.709953 3.892834e+07
1 ALB 41.153300 20.168300 2.877800e+06
2 DZA 28.033900 1.659600 4.385104e+07
3 AND 42.506300 1.521800 7.726500e+04
4 AGO -11.202700 17.873900 3.286627e+07
... ... ... ... ...
185 ZWE -19.015438 29.154857 1.486293e+07
186 AUS -25.000000 133.000000 2.545970e+07
187 CAN 60.000000 -95.000000 3.785570e+07
188 CHN 30.592800 114.305500 1.404676e+09
189 USA 40.000000 -100.000000 3.294663e+08

190 rows × 4 columns

uri = 'https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv'
time_s_raw = pd.read_csv(uri)
time_s_raw
Province/State Country/Region Lat Long 1/22/20 1/23/20 1/24/20 1/25/20 1/26/20 1/27/20 ... 10/22/20 10/23/20 10/24/20 10/25/20 10/26/20 10/27/20 10/28/20 10/29/20 10/30/20 10/31/20
0 NaN Afghanistan 33.939110 67.709953 0 0 0 0 0 0 ... 40626 40687 40768 40833 40937 41032 41145 41268 41334 41425
1 NaN Albania 41.153300 20.168300 0 0 0 0 0 0 ... 18250 18556 18858 19157 19445 19729 20040 20315 20634 20875
2 NaN Algeria 28.033900 1.659600 0 0 0 0 0 0 ... 55357 55630 55880 56143 56419 56706 57026 57332 57651 57942
3 NaN Andorra 42.506300 1.521800 0 0 0 0 0 0 ... 3811 4038 4038 4038 4325 4410 4517 4567 4665 4756
4 NaN Angola -11.202700 17.873900 0 0 0 0 0 0 ... 8582 8829 9026 9381 9644 9871 10074 10269 10558 10805
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
263 NaN West Bank and Gaza 31.952200 35.233200 0 0 0 0 0 0 ... 49134 49579 49989 50442 50952 51528 51948 52571 53075 53520
264 NaN Western Sahara 24.215500 -12.885800 0 0 0 0 0 0 ... 10 10 10 10 10 10 10 10 10 10
265 NaN Yemen 15.552727 48.516388 0 0 0 0 0 0 ... 2057 2060 2060 2060 2060 2060 2061 2062 2062 2063
266 NaN Zambia -13.133897 27.849332 0 0 0 0 0 0 ... 16035 16095 16117 16117 16200 16243 16285 16325 16415 16432
267 NaN Zimbabwe -19.015438 29.154857 0 0 0 0 0 0 ... 8242 8257 8269 8276 8303 8315 8320 8349 8362 8367

268 rows × 288 columns

time_s = time_s_raw.groupby('Country/Region').agg(dict(zip(time_s_raw.columns[4:], ['sum']*(len(time_s_raw.columns)-4))))
time_s = time_s.reset_index()
time_s
Country/Region 1/22/20 1/23/20 1/24/20 1/25/20 1/26/20 1/27/20 1/28/20 1/29/20 1/30/20 ... 10/22/20 10/23/20 10/24/20 10/25/20 10/26/20 10/27/20 10/28/20 10/29/20 10/30/20 10/31/20
0 Afghanistan 0 0 0 0 0 0 0 0 0 ... 40626 40687 40768 40833 40937 41032 41145 41268 41334 41425
1 Albania 0 0 0 0 0 0 0 0 0 ... 18250 18556 18858 19157 19445 19729 20040 20315 20634 20875
2 Algeria 0 0 0 0 0 0 0 0 0 ... 55357 55630 55880 56143 56419 56706 57026 57332 57651 57942
3 Andorra 0 0 0 0 0 0 0 0 0 ... 3811 4038 4038 4038 4325 4410 4517 4567 4665 4756
4 Angola 0 0 0 0 0 0 0 0 0 ... 8582 8829 9026 9381 9644 9871 10074 10269 10558 10805
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
185 West Bank and Gaza 0 0 0 0 0 0 0 0 0 ... 49134 49579 49989 50442 50952 51528 51948 52571 53075 53520
186 Western Sahara 0 0 0 0 0 0 0 0 0 ... 10 10 10 10 10 10 10 10 10 10
187 Yemen 0 0 0 0 0 0 0 0 0 ... 2057 2060 2060 2060 2060 2060 2061 2062 2062 2063
188 Zambia 0 0 0 0 0 0 0 0 0 ... 16035 16095 16117 16117 16200 16243 16285 16325 16415 16432
189 Zimbabwe 0 0 0 0 0 0 0 0 0 ... 8242 8257 8269 8276 8303 8315 8320 8349 8362 8367

190 rows × 285 columns

time_s.loc[time_s['Country/Region']=='Korea, South', 'Country/Region'] = 'South Korea'
time_s.loc[time_s['Country/Region']=="Cote d'Ivoire", 'Country/Region'] = 'Ivory Coast'
time_s.loc[time_s['Country/Region']=='Timor-Leste', 'Country/Region'] = 'East Timor'
time_s.loc[time_s['Country/Region']=='Taiwan*', 'Country/Region'] = 'Taiwan'
time_s.loc[time_s['Country/Region']=='Burma', 'Country/Region'] = 'Myanmar'
time_s.loc[time_s['Country/Region']=='US', 'Country/Region'] = 'United States of America'
time_s.loc[time_s['Country/Region']=='Czech Republic', 'Country/Region'] = 'Czechia'
time_s.loc[time_s['Country/Region']=='North Macedonia', 'Country/Region'] = 'Macedonia'
time_s.loc[time_s['Country/Region']=='Bahamas', 'Country/Region'] = 'The Bahamas'
time_s.loc[time_s['Country/Region']=='Congo (Kinshasa)', 'Country/Region'] = 'Democratic Republic of the Congo'
time_s.loc[time_s['Country/Region']=='Congo (Brazzaville)', 'Country/Region'] = 'Republic of the Congo'
time_s_T = time_s.set_index('Country/Region').T
time_s_T
Country/Region Afghanistan Albania Algeria Andorra Angola Antigua and Barbuda Argentina Armenia Australia Austria ... United Kingdom Uruguay Uzbekistan Venezuela Vietnam West Bank and Gaza Western Sahara Yemen Zambia Zimbabwe
1/22/20 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
1/23/20 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 2 0 0 0 0 0
1/24/20 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 2 0 0 0 0 0
1/25/20 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 2 0 0 0 0 0
1/26/20 0 0 0 0 0 0 0 0 4 0 ... 0 0 0 0 2 0 0 0 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
10/27/20 41032 19729 56706 4410 9871 124 1116609 80410 27553 86102 ... 920664 2916 65881 90400 1172 51528 10 2060 16243 8315
10/28/20 41145 20040 57026 4517 10074 124 1130533 82651 27565 89496 ... 945378 2981 66141 90876 1173 51948 10 2061 16285 8320
10/29/20 41268 20315 57332 4567 10269 124 1143800 85034 27579 93949 ... 968456 3044 66392 91280 1177 52571 10 2062 16325 8349
10/30/20 41334 20634 57651 4665 10558 127 1157179 87432 27585 99576 ... 992874 3082 66628 91589 1177 53075 10 2062 16415 8362
10/31/20 41425 20875 57942 4756 10805 128 1166924 89813 27595 104925 ... 1014793 3124 66932 92013 1180 53520 10 2063 16432 8367

284 rows × 190 columns

time_s_T = time_s_T.apply(lambda x: x.diff(), axis=0)
time_s_T
Country/Region Afghanistan Albania Algeria Andorra Angola Antigua and Barbuda Argentina Armenia Australia Austria ... United Kingdom Uruguay Uzbekistan Venezuela Vietnam West Bank and Gaza Western Sahara Yemen Zambia Zimbabwe
1/22/20 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1/23/20 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 0.0 0.0
1/24/20 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
1/25/20 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
1/26/20 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 4.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
10/27/20 95.0 284.0 287.0 85.0 227.0 0.0 14308.0 1600.0 14.0 2835.0 ... 22924.0 44.0 214.0 353.0 3.0 576.0 0.0 0.0 43.0 12.0
10/28/20 113.0 311.0 320.0 107.0 203.0 0.0 13924.0 2241.0 12.0 3394.0 ... 24714.0 65.0 260.0 476.0 1.0 420.0 0.0 1.0 42.0 5.0
10/29/20 123.0 275.0 306.0 50.0 195.0 0.0 13267.0 2383.0 14.0 4453.0 ... 23078.0 63.0 251.0 404.0 4.0 623.0 0.0 1.0 40.0 29.0
10/30/20 66.0 319.0 319.0 98.0 289.0 3.0 13379.0 2398.0 6.0 5627.0 ... 24418.0 38.0 236.0 309.0 0.0 504.0 0.0 0.0 90.0 13.0
10/31/20 91.0 241.0 291.0 91.0 247.0 1.0 9745.0 2381.0 10.0 5349.0 ... 21919.0 42.0 304.0 424.0 3.0 445.0 0.0 1.0 17.0 5.0

284 rows × 190 columns

Just get the sum of last 7 days - that's all you need per country.

hot_spots = time_s_T.tail(7).sum().to_frame(name="past_7_days").reset_index().rename(columns={'Country/Region': 'Country_Region'})
hot_spots.past_7_days = hot_spots.past_7_days/7
hot_spots
Country_Region past_7_days
0 Afghanistan 93.857143
1 Albania 288.142857
2 Algeria 294.571429
3 Andorra 102.571429
4 Angola 254.142857
... ... ...
185 West Bank and Gaza 504.428571
186 Western Sahara 0.000000
187 Yemen 0.428571
188 Zambia 45.000000
189 Zimbabwe 14.000000

190 rows × 2 columns

world = world.merge(hot_spots, on='Country_Region', how='inner')
world.info()
<class 'geopandas.geodataframe.GeoDataFrame'>
Int64Index: 167 entries, 0 to 166
Data columns (total 6 columns):
 #   Column          Non-Null Count  Dtype   
---  ------          --------------  -----   
 0   Country_Region  167 non-null    object  
 1   NAME            167 non-null    object  
 2   iso3            167 non-null    object  
 3   CONTINENT       167 non-null    object  
 4   geometry        167 non-null    geometry
 5   past_7_days     167 non-null    float64 
dtypes: float64(1), geometry(1), object(4)
memory usage: 9.1+ KB
world = world.merge(population_data, on='iso3', how='left')
world
Country_Region NAME iso3 CONTINENT geometry past_7_days Lat Long_ Population
0 Fiji Fiji FJI Oceania MULTIPOLYGON (((180.00000 -16.06713, 180.00000... 0.142857 -17.713400 178.065000 896444.0
1 Tanzania Tanzania TZA Africa POLYGON ((33.90371 -0.95000, 34.07262 -1.05982... 0.000000 -6.369028 34.888822 59734213.0
2 Western Sahara W. Sahara ESH Africa POLYGON ((-8.66559 27.65643, -8.66512 27.58948... 0.000000 24.215500 -12.885800 597330.0
3 Canada Canada CAN North America MULTIPOLYGON (((-122.84000 49.00000, -122.9742... 3037.428571 60.000000 -95.000000 37855702.0
4 United States of America United States of America USA North America MULTIPOLYGON (((-122.84000 49.00000, -120.0000... 78380.571429 40.000000 -100.000000 329466283.0
... ... ... ... ... ... ... ... ... ...
162 Serbia Serbia SRB Europe POLYGON ((18.82982 45.90887, 18.82984 45.90888... 1154.571429 44.016500 21.005900 8737370.0
163 Montenegro Montenegro MNE Europe POLYGON ((20.07070 42.58863, 19.80161 42.50009... 244.571429 42.708678 19.374390 628062.0
164 Kosovo Kosovo -99 Europe POLYGON ((20.59025 41.85541, 20.52295 42.21787... 224.428571 NaN NaN NaN
165 Trinidad and Tobago Trinidad and Tobago TTO North America POLYGON ((-61.68000 10.76000, -61.10500 10.890... 27.000000 10.691800 -61.222500 1399491.0
166 South Sudan S. Sudan SSD Africa POLYGON ((30.83385 3.50917, 29.95350 4.17370, ... 3.857143 6.877000 31.307000 11193729.0

167 rows × 9 columns

world = world.assign(average_daily_per_capita = (world.past_7_days/world.Population)*100000)
world
Country_Region NAME iso3 CONTINENT geometry past_7_days Lat Long_ Population average_daily_per_capita
0 Fiji Fiji FJI Oceania MULTIPOLYGON (((180.00000 -16.06713, 180.00000... 0.142857 -17.713400 178.065000 896444.0 0.015936
1 Tanzania Tanzania TZA Africa POLYGON ((33.90371 -0.95000, 34.07262 -1.05982... 0.000000 -6.369028 34.888822 59734213.0 0.000000
2 Western Sahara W. Sahara ESH Africa POLYGON ((-8.66559 27.65643, -8.66512 27.58948... 0.000000 24.215500 -12.885800 597330.0 0.000000
3 Canada Canada CAN North America MULTIPOLYGON (((-122.84000 49.00000, -122.9742... 3037.428571 60.000000 -95.000000 37855702.0 8.023702
4 United States of America United States of America USA North America MULTIPOLYGON (((-122.84000 49.00000, -120.0000... 78380.571429 40.000000 -100.000000 329466283.0 23.790165
... ... ... ... ... ... ... ... ... ... ...
162 Serbia Serbia SRB Europe POLYGON ((18.82982 45.90887, 18.82984 45.90888... 1154.571429 44.016500 21.005900 8737370.0 13.214176
163 Montenegro Montenegro MNE Europe POLYGON ((20.07070 42.58863, 19.80161 42.50009... 244.571429 42.708678 19.374390 628062.0 38.940651
164 Kosovo Kosovo -99 Europe POLYGON ((20.59025 41.85541, 20.52295 42.21787... 224.428571 NaN NaN NaN NaN
165 Trinidad and Tobago Trinidad and Tobago TTO North America POLYGON ((-61.68000 10.76000, -61.10500 10.890... 27.000000 10.691800 -61.222500 1399491.0 1.929273
166 South Sudan S. Sudan SSD Africa POLYGON ((30.83385 3.50917, 29.95350 4.17370, ... 3.857143 6.877000 31.307000 11193729.0 0.034458

167 rows × 10 columns

alt.Chart(world).mark_geoshape(stroke='white').encode(
    color=alt.Color('average_daily_per_capita:Q'),
    tooltip = ['Country_Region:N', 'average_daily_per_capita:Q']
).properties(width=1400, height=800).project('equalEarth').configure_view(strokeWidth=0)
world = world.assign(Average_Daily_Cases = world.average_daily_per_capita.apply(lambda x: 16 if x>14 else x))
color_scale = ['#f2df91', '#f9c467', '#ffa83e', '#ff8b24', '#fd6a0b', '#f04f09', '#e13107', '#ce0a05']
grey = "#f2f2f2"
world_map = alt.Chart(world).mark_geoshape(stroke='white').encode(
    color=alt.Color('Average_Daily_Cases:Q', scale=alt.Scale(range=color_scale), bin=alt.Bin(base=2, step=2, extent=[0,16])),
    tooltip = ['Country_Region:N', 'average_daily_per_capita:Q']
).properties(width=1400, height=600).project('equalEarth')
world_map.configure_view(strokeWidth=0)

This is a custom color scale. Exact results with countries that do not publish data can only be reached when we scale color using a color field. Otherwise this is the best we can do.