Python Geopandas: Exclude French Guiana from Europe Map - python

I am writing a code for a map of europe with python geopandas.
I am currently facing a problem with French Guiana. I don't want it to display in the map, however, I don't find a way to detach it from France.
Here is my code:
import geopandas as gpd
import pandas as pd
import matplotlib.pyplot as plt
europe = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
europe = europe[europe.continent == 'Europe']
#europe = europe[europe.name != 'France']
data = pd.read_csv('HICP_EU_bycountry_12_2022.csv', delimiter=';')
data = data[['Area', 'Rate']]
merged_data = europe.merge(data, left_on='name', right_on='Area', how='left')
fig, ax = plt.subplots(figsize=(10, 6))
merged_data.plot(column='Rate', cmap='Reds', linewidth=0.8, ax=ax, edgecolor='0.8', legend=True)
ax.set_title('Inflation Rates in Europe', fontsize=16)
ax.set_axis_off()
for idx, row in merged_data.iterrows():
rate = row['Rate']
if not pd.isna(rate):
ax.annotate(text=str(rate), xy=row['geometry'].centroid.coords[0], horizontalalignment='center', fontsize=8)
ax.set_facecolor('#f7f7f7')
plt.show()

Related

How to plot only max values using python

I want to make a graph about how the maximum value of a cluster of points at any given x coordinate changes over time.
What I have achieved so far:
What I want to achieve:
I was thinking that making a subset of the data with only the day and value, and then getting the maximum value of the array either by iterating trough it or using a function. But I don't know if it's possible like here:
Here's my code
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('strong.csv', names=[
'time', 'exercise', 'set_number', 'mass', 'reps'],parse_dates=['time'])
df.time = pd.to_datetime(df.time,format='%Y-%m-%d')
df_exercise = df[(df.exercise == 'Bench Press (Barbell)')]
fig, ax = plt.subplots()
ax.scatter(
df_exercise.time,df_exercise.mass, c='Orange', s=30
)
ax.set(xlabel='Day', ylabel='Weight [ kg ]',
title='Time/Weight')
plt.xticks(fontsize=8,rotation=45)
plt.show()
plt.savefig('grafic.png')
You could group the dataframe by date and aggregate the maxima:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
df = pd.DataFrame({'time': np.repeat(pd.date_range('2021-03-01', periods=6), 2),
'mass': np.random.randint(20, 56, 12),
'excersie': 'Bench Press (Barbell)'})
df.time = pd.to_datetime(df.time, format='%Y-%m-%d')
df_exercise = df # just creating a dataframe similar to the question's
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 5))
ax1.scatter(df_exercise.time, df_exercise.mass, c='limegreen', s=30)
df_plot = df_exercise.groupby('time')['mass'].agg('max')
ax2.scatter(df_exercise.time, df_exercise.mass, c='limegreen', s=30, alpha=0.3)
ax2.scatter(df_plot.index, df_plot.values, c='orange', s=30)
ax2.plot(df_plot.index, df_plot.values, c='black', lw=2, zorder=0)
for ax in (ax1, ax2):
ax.set(xlabel='Day', ylabel='Weight [ kg ]', title='Time/Weight')
ax.tick_params(axis='x', labelsize=8, labelrotation=45)
plt.tight_layout()
plt.show()

How to plot labels for some cites on the map? using cartopy

I have an excel file with the information of some cites, now I want to plot those cites with their name on the map. I wrote the following codes, however, I can't get the name of the cites properly. For each cite I get a label with the whole list of 'name'.Any suggestion is welcome.
#I could not install PyGMT or basemap or even geopandas,so I just have cartopy.
import pandas as pd
import csv
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
df = pd.read_excel('./seismogram.xlsx')
lon = df['longitude'].to_list()
lat = df['latitude '].to_list()
name = (df['code']).to_list()
def main():
fig = plt.figure(figsize=(15,15))
plt.rcParams["font.size"] = 18
ax = fig.add_subplot(1,1,1, projection=ccrs.PlateCarree())
ax.set_extent([128, 133, 30, 35], crs=ccrs.PlateCarree())
ax.set_title("Japan")
ax.coastlines(resolution='10m')
ax.add_feature(cfeature.BORDERS, linestyle=':')
ax.stock_img()
return fig, ax
fig, ax = main()
ax.scatter(lon, lat, color="r", marker="o", s = 15)
zip_object = zip(lon, lat, name)
for (lg, lt, ne) in zip_object:
ax.text(lg - .05, lt + .05,
name,
va='center',
ha='right', transform=ccrs.Geodetic(), fontweight='bold')
plt.show()
From your for-loop, I'm 99% certain you should be using ne in place of name:
zip_object = zip(lon, lat, name)
for (lg, lt, ne) in zip_object:
ax.text(lg - .05, lt + .05,
ne,
va='center',
ha='right', transform=ccrs.Geodetic(), fontweight='bold')
Easy mistake to make :)

How to shift table location using .plot(table = True) for Matplotlib

Currently I am using .plot(table=True) to display the tables and this is my current output:
May I know how can I shift the table down?
Here is my code:
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
import numpy as np
sns.set()
df = pd.read_csv('file.csv')
df['year'] = pd.DatetimeIndex(df['month']).year
df.head()
ax = df.groupby(['year', 'child_gender'])['birth_count'].count().unstack('child_gender').fillna(0).plot(
kind='line',
stacked=False,
marker='o',
table = True)
plt.xticks(np.arange(2016,2019,1))
plt.legend(title='Child Gender', bbox_to_anchor=(1.0, 1), loc='upper left')
plt.ylabel('Birth Count')
plt.xlabel('Year')
plt.title("Total Birth Count By Child Gender")
plt.autoscale(enable=False)
plt.tight_layout()
plt.show()
this is the current dataframe I have:
Use bbox
dont use table=True, instead create a table under the plot using plt.table
fig, ax = plt.subplots(figsize=(5,8))
df.plot(ax=ax)
plt.table(cellText=df.values,
loc='center left',
rowLabels=['f','m'],
colLabels=['2016','2017','2018'],
bbox=[0.0, -0.2, 1, 0.1])
Using second value in bbox list you can move it as much as you want

geopandas plotting with legend filled up with slash lines

I use different colors and patterns to show three counties on the PA map. The Centre County is represented by the slash lines using hatch='\\'. But I got difficulties to show such pattern on the legend.
I kind of know that this is not going to work, but I tried Line2D([0],[0],color='white',hatch='\\',lw=4,label='Centre County'), and got errors saying something like "hatch is not an attribute".
%matplotlib inline
import geopandas as gpd
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
fig, ax = plt.subplots(1,figsize=(8,8))
pa.plot(ax=ax,color='white',edgecolor='grey')
centre.plot(ax=ax,color='white',hatch='\\\\\\\\',edgecolor='black')
pike.plot(ax=ax,color='grey')
perry.plot(ax=ax,color='red')
LegendElement = [
Line2D([0],[0],color='red',lw=4,label='Perry County'),
Line2D([0],[0],color='grey',lw=4,label='Pike County'),
Line2D([0],[0],color='white',lw=4,label='Centre County')
]
ax.legend(handles=LegendElement,loc='upper right')
When you create polygons, the property facecolor defines the fill color. And to create correct legend for polygon features, mpatches.Patch is needed.
Here is the code that demonstrates how to use facecolor, and mpatches.Patch:
import geopandas as gpd
import matplotlib.pyplot as plt
#from matplotlib.lines import Line2D
import matplotlib.patches as mpatches
from cartopy import crs as ccrs
#fig, ax = plt.subplots(1,figsize=(8,8))
fig, ax = plt.subplots(figsize=(9,9), subplot_kw={'projection': ccrs.PlateCarree()})
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
# cities = gpd.read_file(gpd.datasets.get_path('naturalearth_cities'))
asia = world[(world.continent == "Asia")] #take Asia countries
asia.plot(ax=ax, color="lightgreen")
china = asia[(asia.name == "China")]
india = asia[(asia.name == "India")]
saudi = asia[(asia.name == "Saudi Arabia")]
ax.add_geometries(china['geometry'], crs=ccrs.PlateCarree(), \
facecolor='w', hatch='\\\\\\\\', edgecolor='k', label='China')
ax.add_geometries(india['geometry'], crs=ccrs.PlateCarree(), \
color='grey', label='India')
ax.add_geometries(saudi['geometry'], crs=ccrs.PlateCarree(), \
color='red', label='Saudi Arabia')
LegendElement = [
mpatches.Patch(facecolor='w', hatch='\\\\\\\\', edgecolor='k', label='China'),
mpatches.Patch(color='grey', label='India'),
mpatches.Patch(color='red', label='Saudi Arabia')
]
ax.legend(handles = LegendElement, loc='upper right')
plt.show()
The output plot looks like this:

Plot dual axis graph using DataFrame

I have a DataFrame that looks like this:
state runtime pixels segments
0 Texas 0.079277 1756374 12960
1 California 0.045553 1221211 5129
2 Rhode Island 0.002466 8134 1247
3 Washington 0.016046 339786 6854
4 Alabama 0.009114 214936 1930
5 District of Columbia 0.000799 506 218
6 Ohio 0.007617 192800 2949
I am trying to plot this DataFrame with a dual y-axis along a shared x-axis (runtime)
I have done this with the below code:
import pandas as pd
import matplotlib.pyplot as plt
from pylab import figure, show, legend, ylabel
data = pd.read_excel('runtimes.xlsx')
## create the general figure
fig1 = figure()
ax1 = fig1.add_subplot(111)
ax1.plot(data[['runtime', 'pixels']].T)
ax1.set_ylabel('Pixels')
ax1.set_xlabel('Runtime (s)')
ax2 = ax1.twinx()
ax2.plot(data[['runtime', 'segments']].T)
ax2.set_ylabel('Segments', color='r')
for tl in ax2.get_yticklabels():
tl.set_color('r')
Which gives me this graph:
There are two problems I am trying to fix:
(1) This plots each row twice when I only want it to plot once - how can I fix this?
(2) How can I add a legend so you can tell which line indicates its proper state?
I find that it is usually easier to be explicit about the columns, instead of allowing pandas to do everything automatically, for these kinds of cases. E.g.
ax1.scatter(data['runtime'], data['pixels'])
and
ax2.scatter(data['runtime'], data['segments'])
For a complete example demonstrating this:
import pandas as pd
import matplotlib.pyplot as plt
from pylab import figure, show, legend, ylabel
data = pd.DataFrame({'runtime': [0.079277, 0.045553, 0.002466, 0.016046, 0.009114,
0.000799, 0.007617],
'pixels': [1756374, 1221211, 8134, 339786, 214936, 506, 192800],
'segments':[12960, 5129, 1247, 6854, 1930, 218, 2949]})
## create the general figure
fig1 = figure()
ax1 = fig1.add_subplot(111)
ax1.scatter(data['runtime'], data['pixels'], label="Pixels", marker='.', color='k')
ax1.set_ylabel('Pixels')
ax1.set_xlabel('Runtime (s)')
ax2 = ax1.twinx()
ax2.scatter(data['runtime'], data['segments'], label="Segments", marker='.', color='r')
ax2.set_ylabel('Segments', color='r')
for tl in ax2.get_yticklabels():
tl.set_color('r')
fig1.legend(bbox_to_anchor=(0.225,0.845))
plt.show()
You may also note the legend, you can change the location as you want by changing the bbox_to_anchor tuple, docs
Edit
If you need to color based on state then you can do something like this
import pandas as pd
import matplotlib.pyplot as plt
from pylab import figure, show, legend, ylabel
import matplotlib.lines as mlines
data = pd.DataFrame({'state': ["Texas", "California", "Rhode Island", "Washington",
"Alabama", "District of Columbia", "Ohio"],
'runtime': [0.079277, 0.045553, 0.002466, 0.016046,
0.009114, 0.000799, 0.007617],
'pixels': [1756374, 1221211, 8134, 339786, 214936, 506, 192800],
'segments':[12960, 5129, 1247, 6854, 1930, 218, 2949]})
## create the general figure
fig1 = figure()
ax1 = fig1.add_subplot(111)
ax2 = ax1.twinx()
for ii in range(len(data['state'])):
ax1.scatter(data['runtime'][ii], data['pixels'][ii],
label=data['state'][ii], marker='.')
ax2.scatter(data['runtime'][ii], data['segments'][ii], marker='+')
ax1.set_ylabel('Pixels')
ax1.set_xlabel('Runtime (s)')
legend = fig1.legend(bbox_to_anchor=(0.3,0.845))
m1 = mlines.Line2D([], [], color='black', linewidth = 0, marker='.', label='Pixels')
m2 = mlines.Line2D([], [], color='black', linewidth = 0, marker='+', label='Segments')
plt.legend(handles=[m1,m2], loc='lower right')
ax2.set_ylabel('Segments', color='r')
for tl in ax2.get_yticklabels():
tl.set_color('r')
plt.show()

Categories