Visualizing commerce circulate in Python maps — Half I: Bi-directional commerce circulate maps #Imaginations Hub

Image source - Pexels.com


Visualizing commerce circulate in Python maps — Half I: Bi-directional commerce circulate maps

The change of products and providers in change for his or her corresponding values is an intricate a part of our each day life. Equally, international locations have interaction in several sorts of commerce relationships for the change of services resembling electrical energy, power commodities, uncooked supplies, processed items, tourism, and so on. Understanding the commerce circulate between international locations (import and export) is essential to assessing the earnings and expenditure of a rustic, the financial prowess, the safety of provide, and the character of the connection between international locations.

On this two-part sequence, I’m going to share how the commerce circulate between international locations will be visualized in maps utilizing Python. The primary a part of this sequence will give attention to visualizing the two-way (imports and exports) commerce circulate between international locations. The second half will give attention to visualizing the internet commerce circulate between international locations. I’m going to make use of dummy datasets of a hypothetical product for this visualization. I’ll spotlight my nation and area (Nepal/South Asia) for instance for the demonstration goal. Let’s get began.

Picture by GeoJango Maps on Unsplash

Discovering Coordinates of Arrows

Within the commerce circulate maps, I aimed to signify two-way commerce relationships between international locations. For instance, the export from Nepal to India could be represented by the primary arrow (A1-A2) and the import by Nepal from India could be represented by a second arrow (A3-A4). On this method, every nation pair relationship would require 4 coordinate factors to outline the beginning and finish factors of arrows to signify exports and imports respectively.

Whereas additionally it is doable to imagine a coordinate that may be detected robotically (for instance, the centroid of a rustic geometry), I meant to mark the factors in a map and get their coordinates individually. For this goal, it’s doable to create a challenge in an utility resembling Google Earth, export a KML file, and extract the coordinates with a converter (for instance, the GIS information converter within the web site of MyGeodata Cloud).

Keyhole Markup Language (KML) is a file format used to show geographic information in an utility resembling Google Earth. It makes use of a tag-based construction with nested components and attributes and relies on the XML normal (Google, 2023).

Information

The construction of my enter information appears to be like as proven within the picture beneath. It comprises 5 completely different commerce relationships between neighboring international locations: Nepal-India, Nepal-Bangladesh, Nepal-China, India-Pakistan, and India-Sri Lanka. For every nation pair, there are 4 coordinate factors for the beginning and finish factors of the 2 arrows. Value1 represents the export from Country1 to Country2. Value2 represents the import by Country1 from Country2. The purpose is to show this relationship in a Python map.

Information enter for commerce circulate maps. Picture by Creator.

I learn the above information as a pandas dataframe df. Moreover, I created dictionary objects resembling transfers containing the export and import quantity between every nation pair, and startarrow1_dict containing the coordinate of place to begin of the primary arrow.

Creating essential dictionary objects. Picture by Creator.

Code description

On this part, I’ll describe the code used to visualise the commerce circulate maps. I’ll primarily use the matplotlib and cartopy packages. I’ve additionally used the identical packages to visualise the worldwide floor temperature anomaly in certainly one of my earlier posts.

  1. Import required packages

I began with importing the principle required packages and dependencies as proven beneath:

import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib import colormaps
from matplotlib.colours import Normalize
from matplotlib.cm import ScalarMappable

import numpy as np
import pandas as pd
import os

2. Learn the form file

As a form file, I used the Pure Earth Vector. The vector file will be learn straight by the shapereader module of the cartopy bundle.

# get the nation border file (10m decision) and extract
shpfilename = shpreader.natural_earth(
decision=”10m”,
class=”cultural”,
title=”admin_0_countries”,
)
reader = shpreader.Reader(shpfilename)
international locations = reader.data()

Utilizing a bundle referred to as Fiona, it’s doable to learn the checklist of all international locations as proven beneath.

Fiona bundle is used to open the form file and extract the checklist of all nation names. Picture by Creator.

3. Extract the data of solely required international locations

Subsequent, I created required, which is a listing of six international locations having commerce relationships. I additionally created a dictionary object c, which contained the FionaRecord i.e., all related info of the international locations that can be utilized for plotting.

# required international locations
required = [“Nepal”, “India”, “Bangladesh”,”China”,”Pakistan”,”Sri Lanka”]

# extract the precise nation info
c =
co.attributes["ADMIN"]: co
for co in international locations if co.attributes["ADMIN"] in required

4. Plot the required international locations and clipping

On this step, first, I plotted the geometries of required international locations in a PlateCarree projection as proven beneath:

Plotting the required international locations. Picture by Creator.

Subsequent, I needed to clip off the geometries of the remainder of the world in order that I might have a magnified view of the six international locations alone. I decided the extent of the utmost and minimal longitude and latitude values respectively that might cowl all six international locations, set the extent for the axes plot, and plotted the international locations. Within the for loop, I additionally added an code that will show the names of the international locations over the centroid geometry of every nation.

The zorder attribute of the matplotlib bundle would decide the drawing order of the artists. Artists with greater zorder are drawn on the high.

# get total boundary field from nation bounds
extents = np.array([c[cn].bounds for cn in c])
lon = [extents.min(0)[0], extents.max(0)[2]]
lat = [extents.min(0)[1], extents.max(0)[3]]

ax = plt.axes(projection=ccrs.PlateCarree())

# get nation centroids
ax.set_extent([lon[0] - 1, lon[1] + 1, lat[0] - 1, lat[1] + 1])

for key, cn in zip(c.keys(),c.values()):
ax.add_geometries(cn.geometry,
crs=ccrs.PlateCarree(),
edgecolor="grey",
facecolor="whitesmoke",
zorder = 1)

# Add nation names
centroid = cn.geometry.centroid

ax.textual content(
centroid.x,
centroid.y,
key, # Assuming 'title' is the attribute containing the nation names
horizontalalignment='middle',
verticalalignment='middle',
rework=ccrs.PlateCarree(),
fontsize=8, # Regulate the font dimension as wanted
colour='black', # Set the colour of the textual content
zorder = 2
)


plt.axis("off")
plt.present()

5. Arrange colormap, add arrow patches, and colour bar.

That is an important part of the code. First, I chosen viridis_r i.e., the reverse colour palette of viridis as my colormap. Subsequent, I decided the minimal and most worth of any commerce values between international locations as tmin and tmax respectively. These values are normalized such that the tmin corresponds to the bottom finish (0) and tmax corresponds to the very best finish (1) of the colormap cmap and used accordingly within the succeeding code.

Then I looped by the transfers and used the FancyArrowPatch object to plot the arrows between international locations. Every arrow object is related to a singular colour col that represents the commerce circulate from one nation to a different. Whereas additionally it is doable to make use of an offset from the coordinates of the primary arrow to plot the second arrow, I’ve specified the coordinates for the second arrow in my code. Within the code, the mutation_scale attribute is used to manage the size of the top of the arrow, and the linewidth attribute is used to manage the width of the principle line.

Lastly, I added the horizontal colorbar beneath the principle plot.

ax = plt.axes(projection=ccrs.PlateCarree())

# get nation centroids
ax.set_extent([lon[0] - 1, lon[1] + 1, lat[0] - 1, lat[1] + 1])

for key, cn in zip(c.keys(),c.values()):
ax.add_geometries(cn.geometry,
crs=ccrs.PlateCarree(),
edgecolor="gray",
facecolor="whitesmoke",
zorder = 1)

# Add nation names
centroid = cn.geometry.centroid

ax.textual content(
centroid.x,
centroid.y,
key, # Assuming 'title' is the attribute containing the nation names
horizontalalignment='middle',
verticalalignment='middle',
rework=ccrs.PlateCarree(),
fontsize=8, # Regulate the font dimension as wanted
colour='black', # Set the colour of the textual content
zorder = 2
)

# arrange a colormap
cmap = colormaps.get("viridis_r")
tmin = np.array([v for v in transfers.values()]).min()
tmax = np.array([v for v in transfers.values()]).max()
norm = Normalize(tmin, tmax)

for tr in transfers:
c1, c2 = tr.cut up(",")
startarrow1 = startarrow1_dict[tr]
endarrow1 = endarrow1_dict[tr]

startarrow2 = startarrow2_dict[tr]
endarrow2 = endarrow2_dict[tr]


t1 = transfers[tr][0]
col = cmap(norm(t1))

# Use the arrow perform to attract arrows
arrow = mpatches.FancyArrowPatch(
(startarrow1[0], startarrow1[1]),
(endarrow1[0], endarrow1[1]),
mutation_scale=20, #management the size of head of arrow
colour=col,
arrowstyle='-|>',
linewidth=2, # You may modify the linewidth to manage the arrow physique width
zorder = 3
)
ax.add_patch(arrow)

#OTHER WAY
offset = 1
t2 = transfers[tr][1]
col = cmap(norm(t2))
arrow = mpatches.FancyArrowPatch(
(startarrow2[0], startarrow2[1]),
(endarrow2[0], endarrow2[1]),
mutation_scale=20,
colour=col,
arrowstyle='-|>',
linewidth=2, # You may modify the linewidth to manage the arrow physique width
zorder = 4
)
ax.add_patch(arrow)

sm = ScalarMappable(norm, cmap)
fig = plt.gcf()
cbar = fig.colorbar(sm, ax=ax,
orientation = "horizontal",
pad = 0.05, #distance between principal plot and colorbar
shrink = 0.8, #management size
facet = 20 #management width
)
cbar.set_label("Commerce circulate")

plt.title("Commerce circulate in South Asia")
plt.axis("off")

plt.savefig("trade_flow2_with_labels.jpeg",
dpi = 300)
plt.present()

The top product is proven beneath. In my dummy dataset, the least commerce circulate is export from Sri Lanka to India (53 models), which is represented by yellow colour. The best commerce circulate is export from Bangladesh to Nepal (98 models), which is represented by violet colour.

Bi-directional commerce circulate between international locations represented by arrows between international locations. Picture by Creator.

Conclusion

On this publish, I demonstrated how the commerce circulate between international locations together with export and import relationships will be visualized in a Python map utilizing two arrows. I’ve used the cartopy and matplotlib packages for this goal. Within the second a part of this sequence, I’ll showcase how the “internet” commerce circulate relationship will be visualized whereas highlighting the web exporter and internet importer international locations.

The pocket book for this publish is accessible on this GitHub repository. Thanks for studying!

References

Google Builders, 2023. KML Tutorial | Keyhole Markup Language | Google for Builders. The content material of this web page is licensed beneath the Inventive Commons Attribution 4.0 License


Visualizing commerce circulate in Python maps — Half I: Bi-directional commerce circulate maps was initially printed in In the direction of Information Science on Medium, the place persons are persevering with the dialog by highlighting and responding to this story.


Related articles

You may also be interested in