Issue
i have been trying with geopandas and folium and other common libraries of python. I create myself a little challenge, I make a map and highlight the countries I have been to with a single colour. However, I would like to add more features into it, I want to present a different color of the country if I have been there more than once. For example, taiwan, i have been there once, so it is a orange color, japan, twice, so is a red colur, korea, 3 times, so is a purple color etc... I took reference from matplotlib recently but the code isnt working, is it possible to give me some advice?
here is my code the excel file has 2 columns Column A called 'Country', consists of the name of country like china, japan, germany etc, Column B called 'Visits', consists of how many times I have travelled to a corresponding country.
from google.colab import files
import pandas as pd
import geopandas as gpd
import folium
import matplotlib.cm as cm
import matplotlib.colors as colors
# Uploads file
uploaded = files.upload()
filename = next(iter(uploaded))
# Read Excel file to a pandas DataFrame
df = pd.read_excel(filename)
# world geometry
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
# Merge data with the world data
visited = world.merge(df, left_on='name', right_on='Country')
# map createw
m = folium.Map(location=[0, 0], zoom_start=2)
# boundaries
for _, r in world.iterrows():
sim_geo = gpd.GeoSeries(r['geometry']).simplify(tolerance=0.001)
geo_j = folium.GeoJson(data=sim_geo.to_json(), style_function=lambda x: {'color': 'black'})
folium.Popup(r['name']).add_to(geo_j)
geo_j.add_to(m)
# Function to set the color based on the number of visits
def color(visits):
# Create a colormap for 4+ visits
colormap = cm.get_cmap('YlOrRd')
# Normalize the visits to 0-1
norm = colors.Normalize(vmin=1, vmax=4)
# Get the color from the colormap and convert to hex
rgba = colormap(norm(visits), bytes=True)
return '#{:02x}{:02x}{:02x}'.format(rgba[0], rgba[1], rgba[2])
for _, r in visited.iterrows():
sim_geo = gpd.GeoSeries(r['geometry']).simplify(tolerance=0.001)
geo_j = folium.GeoJson(data=sim_geo.to_json(), style_function=lambda x: {'fillColor': color(r['Visits'])})
folium.Popup(r['name']).add_to(geo_j)
geo_j.add_to(m)
# map
m
Solution
It looks like you could make such a map in a simpler way, just with GeoPandas plotting tools, i.e. without using folium. Say you have these data:
Country | Visits |
---|---|
China | 1 |
Iran | 3 |
Japan | 2 |
North Korea | 3 |
South Africa | 2 |
Venezuela | 4 |
If you store it in a CSV-file, you can extract and show it like this:
import pandas as pd
import geopandas
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import matplotlib.colors as colors
# read a CSV file to a pandas DataFrame
df = pd.read_csv('visited_countries.csv', delimiter='\t')
visited = list(df['Country']) # countries visited
num = list(df['Visits']) # number of visits
# get the countries dataset from Natural Earth
file_with_all_countries = geopandas.datasets.get_path('naturalearth_lowres')
all_gdf = geopandas.read_file(file_with_all_countries)
# set the names of the countries as the index
all_gdf = all_gdf.set_index("name")
# get the data for the visited countries
visited_gdf = all_gdf.loc[visited]
# create a column for the number of visits
visited_gdf["num"] = num
cmap = cm.YlOrRd
# show all the countries with the minimum color from the cmap, indicating 0 visits by default
ax = all_gdf.plot(facecolor=cmap(0), edgecolor='grey')
# paint the visited countries
norm = colors.BoundaryNorm(sorted(set(num)), ncolors=cmap.N, extend='both')
visited_gdf.plot(ax=ax, column='num', legend=True, vmin=min(num), vmax=max(num), cmap=cmap, norm=norm)
plt.title('Country Visits')
plt.show()
Answered By - Ratislaus
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.