Click on folium multipolygon overlays and recive a name of active layers - json

I have many GeoJson layers in the folium map, some are overlapped and some are not, at one point. And I would like to know how I can click on the map and receive a popup (probably) with the name of the layer that exists at this point of the click.
It is area of specie distribution, and I want to click and know what species are there.
I try:
import geopandas as gpd
import folium
import webbrowser
maptotal=folium.Map()
#loading
sp1 = gpd.read_file('sp1.json', driver='GeoJSON')
sp2 = gpd.read_file('sp2.json', driver='GeoJSON')
sp3 = gpd.read_file('sp3.json', driver='GeoJSON')
sp4 = gpd.read_file('sp4.json', driver='GeoJSON')
#Try to create popup
for index, in sp1.iterrows():
mapsp1 = folium.features.GeoJson(sp1.geometry)
popup=folium.Popup("""Specie one""")
popup.add_to(mapsp1)
mapsp1.add_to(maptotal)
for index, in sp2.iterrows():
mapsp2 = folium.features.GeoJson(sp2.geometry)
popup=folium.Popup("""Specie two""")
popup.add_to(mapsp2)
mapsp2.add_to(maptotal)
for index, in sp3.iterrows():
mapsp3 = folium.features.GeoJson(sp3.geometry)
popup=folium.Popup("""Specie three""")
popup.add_to(mapsp3)
mapsp3.add_to(maptotal)
for index, in sp4.iterrows():
mapsp4 = folium.features.GeoJson(sp4.geometry)
popup=folium.Popup("""Specie four""")
popup.add_to(mapsp4)
mapsp4.add_to(maptotal)
#create layers
principal=folium.plugins.MarkerCluster(control=False)
maptotal.add_child(principal)
camadasub1=plugins.FeatureGroupSubGroup(camadaprincipal,'sp1')
maptotal.add_child(camadasub1)
camadasub2=plugins.FeatureGroupSubGroup(camadaprincipal,'sp2')
maptotal.add_child(camadasub2)
camadasub3=plugins.FeatureGroupSubGroup(camadaprincipal,'sp3')
maptotal.add_child(camadasub3)
camadasub4=plugins.FeatureGroupSubGroup(camadaprincipal,'sp4')
maptotal.add_child(camadasub4)
folium.GeoJson('sp1.json').add_to(camadasub1)
folium.GeoJson('sp2.json').add_to(camadasub2)
folium.GeoJson('sp3.json').add_to(camadasub3)
folium.GeoJson('sp4.json').add_to(camadasub4)
folium.LayerControl().add_to(maptotal)
#save and open
maptotal.save("map.html")
webbrowser.open("map.html")
My idea of result:
Map

Related

Plotting Polygons with Folium and Pyproj

I'm trying to plot the boundaries of the localities of Brussels. The system of coordinates of my json file has to be converted to a longlat system to display the Polygons on Folium maps. The issue I get is that my coordinates are projected into the Pacific ocean. I guess it is probably due to the fact that the parameters I set are not the good ones. Please find below my code:
import json
import pyproj
import folium
# Load JSON file
with open("districts.json", "r") as f:
data = json.load(f)
# Create a transformation object
in_proj = pyproj.Proj(proj='utm',zone=31,datum='WGS84')
out_proj = pyproj.Proj(proj='longlat',datum='WGS84')
# Transform the coordinates
features = data["features"]
for feature in features:
coords = feature["geometry"]["coordinates"][0]
coords = [pyproj.transform(in_proj, out_proj, coord[0], coord[1]) for coord in coords]
feature["geometry"]["coordinates"] = [coords]
# Plot the polyggon on a map
m = folium.Map()
folium.GeoJson(data).add_to(m)
m
This corresponds to how my json file is structured:
{"type":"FeatureCollection","features":[{"geometry":{"type":"Polygon","coordinates":[[[152914.748398394,173305.19242333],[152947.4133984,173326.530423339],...,[152961.983398418,173225.325423267],[152914.748398394,173305.19242333]]]},...
(https://i.stack.imgur.com/SuU4Q.png)
(https://i.stack.imgur.com/oIKJN.png)
Does anyone has an idea how to solve this? How could I find the right parameters?
I tried different zones but I would rather know of to find the right zone number and understand how it works.

Image locating with pyautogui

With pyautogui I'm trying to locate a object in a screenshot that is being taken but I can't find a way
from pyautogui import *
import pyautogui
import time
import keyboard
import random
import win32api, win32con
time.sleep(2)
ims = pica = pyautogui.screenshot(region=(569,381,800,450))
iml = pyautogui.screenshot(region=(1040,295,100,30))
def click(x,y):
win32api.SetCursorPos((x,y))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0)
#Color of center: (255, 219, 195)
while keyboard.is_pressed('q') == False:
flag = 0
pyautogui.screenshot(region=(1040,295,100,30))
ims.save(r"C:\Users\Billy Bong\Desktop\python\saveimage.png")
pica = pyautogui.screenshot(region=(569,381,800,450))
ims.save(r"C:\Users\Billy Bong\Desktop\python\saveimage2.png")
time.sleep (2)
pyautogui.locateAllOnScreen("saveimage.png", confidence=0.6)
print (cords)
pyautogui.click (cords)
time.sleep (10)
break
Here is the minimal code for locating an object on the screen, you should have the image of the object.
import pyautogui as py
import keyboard
while True:
img = py.locateOnScreen("object.png", confidence=0.9) # add path to your object image here
print(img)
if keyboard.is_pressed('q'):
break
there is something i found out about pyautogui if u gonna use locateonscreen or locateallonscreen the image u asking him to locate must be in same folder u running the script from (according to my experience from using VS-code) and idk if there is a way to tell it to set a path for the image u wanna search to (something) so for the current time make sure u include all images u search for in same folder that the script is running from for me it is (E:\coding\game) cuz i make auto bots for games i like
btw locateallonscreenn prints out a list, the "cords" but idk if "pyautogui.click (cords)
" understand that and if it is going to click all the x,y in cords or not

How to load my tensorflow model with ModelCheckpoint callbacks?

I have trained a model and save the weights using ModelCheckpoint:
checkpoint_callback = ModelCheckpoint(
filepath = checkpoint_prefix,
save_weights_only = True,
save_freq = 'epoch')
During the night while my model was training the electricity went off for some time and my computer turned off. Now I opened my Jupyter notebook and I want to load my model without training it from the beginning. How am I supposed to do this without compiling it again and just using the checkpoints?
I also have tensorboard callbacks:
tensorboard_callback = TensorBoard(
log_dir = 'tensorboard_logs\\'+ model_name,
histogram_freq = 5,
write_graph = True,
update_freq = 'epoch')
Since you only saved the weights of your model, you need to reconstruct the graph and then load your last checkpoint weights on it.
So you have to recreate your model and compile it.
For the next time, if you want to save the complete model, so you don't have to compile it again every time you load it, set save_weights_only to False.
It allow you to load your model with keras.models.load_model() and directly fit it after.
model = Sequential()
model.add()
...
model.compile()
And then load your weights:
model.load_weights(checkpoint_prefix)
and then you can use it normaly :
model.fit( ... )

Bokeh: Link Hover tooltips geometrically to subplots

I have multiple categorical heatmap plots that are in a single display that have identical shapes and x,y coordinates. When hovering on any of the subplots I would like the inspection on one plot to trigger a new inspection on all other plots in the grid and display multiple tooltips simultaneously.
I have researched this topic and found similar posts such as:
Bokeh: Synchronizing hover tooltips in linked plots
Takeaway from link above: There are 2 suggested answers to this question, which attempt to mimic hover tooltips with text glyphs, however these implementations are not successful when I copy and run the code on my own computer (the graphs display correctly but the hover text glyphs don't appear). I assume this could be because of Bokeh API updates, but I am unsure. My reputation doesn't allow comments or I'd address this issue there.
Coordinate tooltips across multiple plots #1547
Takeaway from link above: There is no reproducible data so I am not able to recreate the plot listed here, however bryevdv summarizes what I am trying to do quite efficiently which I'll quote below:
Link on geometry. You might want the geometry of the inspection on one plot to trigger a completely new inspection (using that same geometry) on another plot. So if the cursor is at (10.5, 7) on one plot, then the additional plots do a hit test at (10.5, 7) and if there are glyphs that have any hovers a that point, then a hover gets drawn there.
I have created some generalized data to illustrate my problem:
from bokeh.io import show, output_notebook
from bokeh.layouts import gridplot
from bokeh.models import LinearColorMapper, HoverTool
from bokeh.plotting import figure, show, output_file
from bokeh.transform import transform
import numpy as np
import pandas as pd
data1 = [['A','A',100], ['A','B',175], ['B','A',75], ['B','B',200]]
data2 = [['A','A',25], ['A','B',100], ['B','A',50], ['B','B',75]]
data3 = [['A','A',150], ['A','B',75], ['B','A',25], ['B','B',125]]
df1 = pd.DataFrame(data1, columns = ['Left','Right','Value'])
df2 = pd.DataFrame(data2, columns = ['Left','Right','Value'])
df3 = pd.DataFrame(data3, columns = ['Left','Right','Value'])
def heatmap(df, title):
letters = ['A','B']
mapper = LinearColorMapper(palette=['#225ea8', '#41b6c4', '#a1dab4', '#ffffcc'], low=0, high=200)
TOOLS = 'reset'
p = figure(plot_width=255, plot_height=250, title=title,
x_range=letters,
y_range=list(reversed(letters)), x_axis_location='above',
tools=TOOLS, toolbar_location='below')
p.grid.grid_line_color = None
p.grid.grid_line_width = 0.5
p.axis.axis_line_color = None
p.axis.major_tick_line_color = None
p.axis.major_label_text_font_size = '9pt'
p.axis.major_label_standoff = 0
p.xaxis.major_label_orientation = 0
hover = HoverTool()
p.rect(x='Right', y='Left', width=1, height=1, line_color=None, source=df,
fill_color={'field': 'Value', 'transform': mapper})
hover.tooltips = [('Group','#Left #Right'), ('Value','#Value')]
p.tools.append(hover)
return p
output_notebook()
p1 = heatmap(df1, 'Plot 1')
p2 = heatmap(df2, 'Plot 2')
p3 = heatmap(df3, 'Plot 3')
grid = gridplot([[p1,p2,p3]])
show(grid)
Output:
My goal is to be able to observe the values across multiple plots at one time without having to be directed to another page or source, so I am open to alternative ways of doing this that doesn't involve hover tooltips. Thanks!

Using clear_output() with jupyter notebook widgets and google maps api

I am using jupyter notebook to do some mapping visualisation stuff with google maps (via the http://jupyter-gmaps.readthedocs.io/en/latest/gmaps.html library)
I want to be able to use the jupyter dropdown widget to pass it an updated string and get a new map based on this to appear on the page.
All of this works well (code below) but when I run the it, the clear_output() does not work. It works fine if I am not using google maps, like just printing something in the cell once when I change the dropdown.
Does anyone have any idea about this?
import ipywidgets as widgets
import gmaps
import pandas as pd
gmaps.configure(api_key="my api key...")
from IPython.display import display
from IPython.display import clear_output
# global scaling for circle size on map
global SCALING_NORMALIZATION
SCALING_NORMALIZATION = 30
#MAP FUNCTIONS
#function to change circle sizes on map
def create_circle_sizes(values):
scaling_values = []
for i in range(0, len(values)):
a = np.asscalar(values[i])
a = int(a / SCALING_NORMALIZATION)
if a == 0:
scaling_values.append(2)
else:
scaling_values.append(a)
return scaling_values
# function to create hover info on map
def create_hover_info(service_types, names):
hover_info = []
for i in range(0, len(service_types)):
hover_info.append(names[i])
return hover_info
#function to draw a map in gmaps
def create_map(value):
map_df = data[data['lga'] == value][['lat', 'long', 'lic_places', 'sta_name', 'distinct_se_type']]
scaling = map_df['lic_places'].tolist()
names = map_df['sta_name'].tolist()
service_types = map_df['distinct_se_type'].tolist()
map_layer = gmaps.symbol_layer(map_df[['lat', 'long']],
fill_color="blue",
stroke_color="blue",
scale=create_circle_sizes(scaling),
hover_text =
create_hover_info(service_types, names))
fig = gmaps.figure()
fig.add_layer(map_layer)
display(fig)
# WIDGET FUNCTIONS
# function to update the map when dropdown choice is changed
def update_map(args):
# clear_output() doesn't seem to work with map rendering
clear_output()
user_choice = args['new']
create_map(user_choice)
# dropdown widget
dd = widgets.Dropdown(
options=['auburn (c)', 'fairfield (c)', 'penrith (c)'],
value='fairfield (c)',
description='Number:',
disabled=False,
button_style=''
)
#display dropdown widget, with function it will call on change
dd.observe(update_map, 'value')