I have this codeblock to plot a gyro calibration as a compass rose, via a matplotlib polarplot, see the image below. Now I would like to plot the compass on a folium map so at that the observer can see that the Gyro heading does align with the quayside of the port where the ship was moored during the calibration.
How can I plot the polarplot as a transparent (white background is transparent) .png or a .svg @ the position co-ordinates on a folium map?
from pvlib import solarposition
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Polarplot
# user input _____________________________________________________________________________
tz = 'Europe/Amsterdam'
lat = 52+(57/60)+(26.9/3600)
lon = 4+(46/60)+(37.5/3600)
lat_dms, lon_dms ="52°57′26.9″","004°46′37.5″" # position strings
loc_descr = "Den Helder - Nieuwe Diep"
# Corrected gyro heading
gyro_corrected = 154.92
st_dev_gyro = 0.03
# First fix Zn
first_fix = 138.873
# Last fix Zn
last_fix = 144.915
#user input ______________________________________________________________________________
# Function to convert degrees to radians
def degrees_to_radians(degrees):
return degrees * np.pi / 180.0
# Convert angles to radians
gyro_corrected_rad = degrees_to_radians(gyro_corrected)
first_fix_rad = degrees_to_radians(first_fix)
last_fix_rad = degrees_to_radians(last_fix)
# */ solar trajectory plot ------------------------------------------------------------------------------------------------------
# set times for solar trajectory
times = pd.date_range('2019-12-31 00:00:00', '2020-01-01', freq='H', tz=tz)
solpos = solarposition.get_solarposition(times, lat, lon)
# remove nighttime
solpos = solpos.loc[solpos['apparent_elevation'] > 0, :]
#make polarplot
ax = plt.subplot(1, 1, 1, projection='polar')
# /* solar plot ------------------------------------------------------------------------------------------------------
# Plot the corrected gyro heading vector
ax.quiver(0, 0, gyro_corrected_rad, 90, angles='xy', scale_units='xy', scale=1, color='darkgreen', label=f'Gyro Heading True: ({gyro_corrected} ± {st_dev_gyro})°')
# /* solar plot ------------------------------------------------------------------------------------------------------
# draw hour labels
for hour in np.unique(solpos.index.hour):
# choose label position by the smallest radius for each hour
subset = solpos.loc[solpos.index.hour == hour, :]
r = subset.apparent_zenith
pos = solpos.loc[r.idxmin(), :]
ax.text(np.radians(pos['azimuth']), pos['apparent_zenith'], str(hour))
# draw individual days
for date in pd.to_datetime(['2019-12-31']):
times = pd.date_range(date, date+pd.Timedelta('24h'), freq='5min', tz=tz)
solpos = solarposition.get_solarposition(times, lat, lon)
solpos = solpos.loc[solpos['apparent_elevation'] > 0, :]
label = f"☀️ @ {date.strftime('%Y-%m-%d')} -localtime: UTC+1"
ax.plot(np.radians(solpos.azimuth), solpos.apparent_zenith, label=label, color='darkorange', linewidth=2)
# /* solar trajectory plot ------------------------------------------------------------------------------------------------------
# Plot the line for the first fix
ax.plot([0, first_fix_rad], [0, 90], color= 'orange', linestyle='--', label=f'{first_fix}° -fix 1 ☀️')
# Plot the line for the last fix
ax.plot([0, last_fix_rad], [0, 90], color='gold', linestyle='--', label=f'{last_fix}° -last fix ☀️')
# change coordinates to be like a compass
data = pd.DataFrame({'value': [0, 20, 30, 20, 0, 10, 15, 10],
'bearing': range(0, 360, 45),
'compass': ['000°\nN', 'NE', '090°\n E', 'SE', '180°\nS', 'SW', '270°\nW', 'NW']})
data.index = data['bearing'] * 2*np.pi / 360
ax.set_title(f"Sunshot Gyro Calibration @ {lat_dms}N, {lon_dms}E\n{loc_descr}\n")
# Place the legend below the plot
ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.18), fancybox=True, shadow=True, ncol=2) # 1.
ax.set_theta_zero_location('N') # North-up
ax.set_theta_direction(-1)
ax.set_xticklabels(data.compass)
#ax.set_yticklabels()
ax.set_rgrids([])
ax.set_rmax(90)
plt.show()

IIUC, you can savefig with a transparent background, then use it as a FloatImage :
plt.figure(figsize=(4, 2)) # <<< add this
ax = plt.subplot(1, 1, 1, projection='polar')
# rest of the code..
# plt.show() # <<< comment this
import io
import base64
import folium
from folium.plugins import FloatImage
buff = io.BytesIO()
plt.savefig(buff, transparent=True)
img = base64.b64encode(buff.getvalue()).decode()
m = folium.Map([lat, lon], zoom_start=10)
FloatImage(
f"data:image/png;base64,{img}", bottom=30, left=-5
).add_to(m)
Output (m) :

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With