Visualizing GA4 Geographic Data with Python
In this post I just wanted to show a couple of basic examples of how you can display Google Analytics 4 data using Python.
I used a very basic data set of countries and views (pageviews) from my website in Looker Studio.

Above: a Choropleth Map made with Python

Above: a Bubble Map made with Python
Preparing the GA4 data
So before I could create the maps I needed to export and clean the Google Analytics 4 data.

I then exported this data to Google Sheets, where I used TRANSPOSE function to change the data from vertical to horizontal.

I then used the following formula to add in quotation marks in front and behind of each country name.
=ARRAYFORMULA(“‘”&H2:ZZ2&”‘”)

I then used the JOIN formula to include a comma between each country name.
=JOIN(“, “, ARRAYFORMULA(“‘”&H2:ZZ2&”‘”))

I used the following ARRAYFORMULA for adding a comma between each of the views.
=ARRAYFORMULA(H3:ZZ3&”,”)

And then used the CONCATENATE function to combine them all together in one cell.
=CONCATENATE(G18:ES18)

This changed the data into a suitable format for the Python code as shown below.

Here is the Python code containing the countries and views.
import pandas as pd
import plotly.express as px
# Data
data = {
'Country': ['United States', 'United Kingdom', 'India', 'Germany', 'Canada', 'France', 'Australia', 'Brazil', 'Netherlands', 'Indonesia', 'Spain', 'Poland', 'Italy', 'Israel', 'Sweden', 'Thailand', 'South Africa', 'Japan', 'Switzerland', 'Philippines', 'Türkiye', 'Malaysia', 'South Korea', 'Argentina', 'Mexico', 'Taiwan', 'Singapore', 'Belgium', 'New Zealand', 'Denmark', 'Vietnam', 'Ukraine', 'Norway', 'Hong Kong', 'Czechia', 'Pakistan', 'Russia', 'Austria', 'China', 'Portugal', 'Finland', 'Ireland', 'Chile', 'United Arab Emirates', 'Romania', 'Hungary', 'Colombia', 'Greece', 'Saudi Arabia', 'Iran', 'Croatia', 'Lithuania', 'Bulgaria', 'Peru', 'Serbia', 'Egypt', 'Morocco', 'Slovakia', 'Latvia', 'Nigeria', 'Algeria', 'Dominican Republic', 'Bangladesh', 'Sri Lanka', 'Bosnia & Herzegovina', 'Estonia', 'Qatar', 'Guatemala', 'Georgia', 'Lebanon', 'Venezuela', 'Malta', 'Azerbaijan', 'Congo - Kinshasa', '(not set)', 'Ecuador', 'Luxembourg', 'Iceland', 'Kazakhstan', 'Costa Rica', 'Oman', 'Uruguay', 'Jersey', 'Nepal', 'Panama', 'Slovenia', 'Jordan', 'Belarus', 'Madagascar', 'Mauritius', 'Myanmar (Burma)', 'Cambodia', 'Kuwait', 'Kyrgyzstan', 'Moldova', 'North Macedonia', 'Paraguay', 'Tunisia', 'Cyprus', 'Armenia', 'El Salvador', 'Nicaragua', 'Uzbekistan', 'Albania', 'Curaçao', 'Fiji', 'Ghana', 'Jamaica', 'Kenya', 'Libya', 'Mongolia', 'Rwanda', 'Réunion', 'Bahamas', 'Bahrain', 'Barbados', 'Bolivia', 'Ethiopia', 'Honduras', 'Macao', 'Malawi', 'Maldives', 'Montenegro', 'Palestine', 'Tanzania', 'Trinidad & Tobago', 'Zambia', 'Afghanistan', 'Andorra', 'Aruba', 'Belize', 'Bhutan', 'Côte d’Ivoire', 'Grenada', 'Guyana', 'Kosovo', 'Mali', 'Martinique', 'Mayotte', 'Mozambique', 'Papua New Guinea', 'Seychelles', 'Uganda'], # all countries
'Views': [5221,1961,1258,1166,913,848,766,754,621,586,586,460,388,340,334,286,263,257,247,232,229,228,225,214,214,204,203,202,202,169,168,158,153,139,134,133,132,129,126,125,122,121,116,110,99,95,89,76,70,69,56,56,52,50,50,47,45,42,38,37,36,36,34,34,31,30,30,29,26,25,23,22,20,19,18,18,18,17,17,16,16,16,14,14,14,14,13,12,12,12,11,10,10,10,10,10,10,10,9,8,8,8,8,7,6,6,6,6,6,6,6,6,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,] # corresponding views
}
# Creating DataFrame
df = pd.DataFrame(data)
Choropleth Map in Python
I used the following code from ChatGPT to visualize the GA4 data in a choropleth map using Python code.
fig = px.choropleth(df, locations='Country',
locationmode='country names', # Specifies the location format
color='Views', # Specifies the column to color by
hover_name='Country', # Column to be displayed when hovering over each region
color_continuous_scale=px.colors.sequential.Plasma, # Specifies the color scale
title='Country Views') # Title of the chart
# Update figure layout
fig.update_layout(
autosize=False,
width=1000,
height=800,
)
fig.show()


A Bubble Map in Python
# Import necessary libraries
import pandas as pd
import folium
from geopy.geocoders import Nominatim
import math
# Data
{
'Country': ['United States', 'United Kingdom', 'India', 'Germany', 'Canada', 'France', 'Australia', 'Brazil', 'Netherlands', 'Indonesia', 'Spain', 'Poland', 'Italy', 'Israel', 'Sweden', 'Thailand', 'South Africa', 'Japan', 'Switzerland', 'Philippines', 'Türkiye', 'Malaysia', 'South Korea', 'Argentina', 'Mexico', 'Taiwan', 'Singapore', 'Belgium', 'New Zealand', 'Denmark', 'Vietnam', 'Ukraine', 'Norway', 'Hong Kong', 'Czechia', 'Pakistan', 'Russia', 'Austria', 'China', 'Portugal', 'Finland', 'Ireland', 'Chile', 'United Arab Emirates', 'Romania', 'Hungary', 'Colombia', 'Greece', 'Saudi Arabia', 'Iran', 'Croatia', 'Lithuania', 'Bulgaria', 'Peru', 'Serbia', 'Egypt', 'Morocco', 'Slovakia', 'Latvia', 'Nigeria', 'Algeria', 'Dominican Republic', 'Bangladesh', 'Sri Lanka', 'Bosnia & Herzegovina', 'Estonia', 'Qatar', 'Guatemala', 'Georgia', 'Lebanon', 'Venezuela', 'Malta', 'Azerbaijan', 'Congo - Kinshasa', '(not set)', 'Ecuador', 'Luxembourg', 'Iceland', 'Kazakhstan', 'Costa Rica', 'Oman', 'Uruguay', 'Jersey', 'Nepal', 'Panama', 'Slovenia', 'Jordan', 'Belarus', 'Madagascar', 'Mauritius', 'Myanmar (Burma)', 'Cambodia', 'Kuwait', 'Kyrgyzstan', 'Moldova', 'North Macedonia', 'Paraguay', 'Tunisia', 'Cyprus', 'Armenia', 'El Salvador', 'Nicaragua', 'Uzbekistan', 'Albania', 'Curaçao', 'Fiji', 'Ghana', 'Jamaica', 'Kenya', 'Libya', 'Mongolia', 'Rwanda', 'Réunion', 'Bahamas', 'Bahrain', 'Barbados', 'Bolivia', 'Ethiopia', 'Honduras', 'Macao', 'Malawi', 'Maldives', 'Montenegro', 'Palestine', 'Tanzania', 'Trinidad & Tobago', 'Zambia', 'Afghanistan', 'Andorra', 'Aruba', 'Belize', 'Bhutan', 'Côte d’Ivoire', 'Grenada', 'Guyana', 'Kosovo', 'Mali', 'Martinique', 'Mayotte', 'Mozambique', 'Papua New Guinea', 'Seychelles', 'Uganda'], # all countries
'Views': [5221,1961,1258,1166,913,848,766,754,621,586,586,460,388,340,334,286,263,257,247,232,229,228,225,214,214,204,203,202,202,169,168,158,153,139,134,133,132,129,126,125,122,121,116,110,99,95,89,76,70,69,56,56,52,50,50,47,45,42,38,37,36,36,34,34,31,30,30,29,26,25,23,22,20,19,18,18,18,17,17,16,16,16,14,14,14,14,13,12,12,12,11,10,10,10,10,10,10,10,9,8,8,8,8,7,6,6,6,6,6,6,6,6,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,] # corresponding views
}
# Create DataFrame
df = pd.DataFrame(data)
# Get lat, lon for each country
geolocator = Nominatim(user_agent='myGeocoder')
def geolocate(country):
try:
# Geolocate the center of the country
loc = geolocator.geocode(country)
return (loc.latitude, loc.longitude)
except:
# Return missing value
return np.nan
# Apply the function
df['location'] = df['Country'].apply(geolocate)
# Split location column into latitude, longitude
df[['Latitude', 'Longitude']] = pd.DataFrame(df['location'].tolist(), index=df.index)
# Initialize the map
m = folium.Map(location=[0, 0], zoom_start=2)
# Add points to the map
for i in range(0,len(df)):
folium.Circle(
location=[df.iloc[i]['Latitude'], df.iloc[i]['Longitude']],
popup=df.iloc[i]['Country'],
radius=float(df.iloc[i]['Views'])*100,
color='blue',
fill=True,
fill_color='blue'
).add_to(m)
# Show the map
m

