I have a geodataframe with Multistring Geometry. I wanted to plot an interactive map, on which when I click on each line, the name and id would appear! I can see that mouse form would change but nothing will appear. I also tried to define the names as labels but it did not work!
Ex_centreLine_map= folium.Map(location = [43.7180, -79.3762], zoom_start=12)
folium.Choropleth(
centreline_gdf[centreline_gdf.geometry.length> 0.00001],
line_weight=3,
line_color='blue',
popup=centreline_gdf[['lf_name', 'lfn_id']]).add_to(Ex_centreLine_map)
Ex_centreLine_map
you have not provided any sample data, so I have used some road data to make a MWE
you can do native folium however it's simpler to use geopandas explore()
for native folium you can to use folium.GeoJson()
import geopandas as gpd
import pandas as pd
import shapely.wkt
import io
df = pd.read_csv(io.StringIO("""ref;lanes;highway;maxspeed;length;name;geometry
A3015;2;primary;40 mph;40.68;Rydon Lane;MULTILINESTRING ((-3.4851169 50.70864409999999, -3.4849879 50.7090007), (-3.4857269 50.70693379999999, -3.4853034 50.7081574), (-3.488620899999999 50.70365289999999, -3.4857269 50.70693379999999), (-3.4853034 50.7081574, -3.4851434 50.70856839999999), (-3.4851434 50.70856839999999, -3.4851169 50.70864409999999))
A379;3;primary;50 mph;177.963;Rydon Lane;MULTILINESTRING ((-3.4763853 50.70886769999999, -3.4786112 50.70811229999999), (-3.4746017 50.70944449999999, -3.4763853 50.70886769999999), (-3.470350900000001 50.71041779999999, -3.471219399999999 50.71028909999998), (-3.465049699999999 50.712158, -3.470350900000001 50.71041779999999), (-3.481215600000001 50.70762499999999, -3.4813909 50.70760109999999), (-3.4934747 50.70059599999998, -3.4930204 50.7007898), (-3.4930204 50.7007898, -3.4930048 50.7008015), (-3.4930048 50.7008015, -3.4919513 50.70168349999999), (-3.4919513 50.70168349999999, -3.49137 50.70213669999998), (-3.49137 50.70213669999998, -3.4911565 50.7023015), (-3.4911565 50.7023015, -3.4909108 50.70246919999999), (-3.4909108 50.70246919999999, -3.4902349 50.70291189999999), (-3.4902349 50.70291189999999, -3.4897693 50.70314579999999), (-3.4805021 50.7077218, -3.4806265 50.70770150000001), (-3.488620899999999 50.70365289999999, -3.4888806 50.70353719999999), (-3.4897693 50.70314579999999, -3.489176800000001 50.70340539999999), (-3.489176800000001 50.70340539999999, -3.4888806 50.70353719999999), (-3.4865751 50.70487679999999, -3.4882604 50.70375799999999), (-3.479841700000001 50.70784459999999, -3.4805021 50.7077218), (-3.4882604 50.70375799999999, -3.488620899999999 50.70365289999999), (-3.4806265 50.70770150000001, -3.481215600000001 50.70762499999999), (-3.4717096 50.71021009999998, -3.4746017 50.70944449999999), (-3.4786112 50.70811229999999, -3.479841700000001 50.70784459999999), (-3.471219399999999 50.71028909999998, -3.4717096 50.71021009999998))"""),
sep=";")
gdf = gpd.GeoDataFrame(df, geometry=df["geometry"].apply(shapely.wkt.loads), crs="epsg:4326")
gdf.explore(style_kwds={"weight":10})
native folium
import folium
m = folium.Map(
location=[sum(gdf.total_bounds[[1, 3]]) / 2, sum(gdf.total_bounds[[0, 2]]) / 2],
zoom_start=12,
)
def style_fn(x):
return {"color":"blue", "weight":3}
folium.GeoJson(
gdf,
style_function=style_fn,
popup=folium.GeoJsonPopup(gdf.drop(columns=["geometry"]).columns.tolist()),
tooltip=folium.GeoJsonTooltip(["ref"]),
).add_to(m)
m
I have made a scatter plot of the word2vec model using plotly.
I want functionality of highlighting the specific data point on hover along with the top 3 nearest vectors to that.
It would be of great help if anyone can guide me with this or suggest any other option
model
csv
Code:
import gensim
import numpy as np
import pandas as pd
from sklearn.manifold import TSNE
import plotly.express as px
def get_2d_coordinates(model, words):
arr = np.empty((0,100), dtype='f')
labels = []
for wrd_score in words:
try:
wrd_vector = model.wv.get_vector(wrd_score)
arr = np.append(arr, np.array([wrd_vector]), axis=0)
labels.append(wrd_score)
except:
pass
tsne = TSNE(n_components=2, random_state=0)
np.set_printoptions(suppress=True)
Y = tsne.fit_transform(arr)
x_coords = Y[:, 0]
y_coords = Y[:, 1]
return x_coords, y_coords
ic_model = gensim.models.Word2Vec.load("w2v_IceCream.model")
ic = pd.read_csv('ic_prods.csv')
icx, icy = get_2d_coordinates(ic_model, ic['ITEM_DESC'])
ic_data = {'Category': ic['SUB_CATEGORY'],
'Words':ic['ITEM_DESC'],
'X':icx,
'Y':icy}
ic_df = pd.DataFrame(ic_data)
ic_df.head()
ic_fig = px.scatter(ic_df, x=icx, y=icy, color=ic_df['Category'], hover_name=ic_df['Words'], title='IceCream Data')
ic_fig.show()
In plotly-python, I don't think there's an easy way of retrieving the location of the cursor. You can attempt to use go.FigureWidget to highlight a trace as described in this answer, but i think you're going to be limited with with plotly-python and i'm not sure if highlighting the closest n points will be possible.
However, I believe that you can accomplish what you want in plotly-dash since callbacks are supported - meaning you would be able to retrieve location of your cursor and then calculate the n closest data points to your cursor and highlight the data points as needed.
Below is an example of such a solution. If you haven't seen it before, it looks complicated, but what is happening is that I am taking the point where you clicked as an input. plotly is plotly.js under the hood so it comes us in the form of a dictionary (and not some kind of plotly-python object). Then I calculate the closest three data points to the clicked input point by comparing the coordinates of every other point in the dataframe, add the information from the three closest points as traces to the input with the color teal (or any color of your choosing), and send this modified input back as the output, and update the figure.
I am using click instead of hover because hover would cause the highlighted points to flicker too much as you drag your mouse through the points.
Also the dash app doesn't work perfectly as I believe there is some issue when you double click on points (you can see me click once in the gif below before getting it to start working), but this basic framework is hopefully close enough to what you want. Cheers!
import gensim
import numpy as np
import pandas as pd
from sklearn.manifold import TSNE
import plotly.express as px
import plotly.graph_objects as go
import json
import dash
from dash import dcc, html, Input, Output
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
def get_2d_coordinates(model, words):
arr = np.empty((0,100), dtype='f')
labels = []
for wrd_score in words:
try:
wrd_vector = model.wv.get_vector(wrd_score)
arr = np.append(arr, np.array([wrd_vector]), axis=0)
labels.append(wrd_score)
except:
pass
tsne = TSNE(n_components=2, random_state=0)
np.set_printoptions(suppress=True)
Y = tsne.fit_transform(arr)
x_coords = Y[:, 0]
y_coords = Y[:, 1]
return x_coords, y_coords
ic_model = gensim.models.Word2Vec.load("w2v_IceCream.model")
ic = pd.read_csv('ic_prods.csv')
icx, icy = get_2d_coordinates(ic_model, ic['ITEM_DESC'])
ic_data = {'Category': ic['SUB_CATEGORY'],
'Words':ic['ITEM_DESC'],
'X':icx,
'Y':icy}
ic_df = pd.DataFrame(ic_data)
ic_fig = px.scatter(ic_df, x=icx, y=icy, color=ic_df['Category'], hover_name=ic_df['Words'], title='IceCream Data')
NUMBER_OF_TRACES = len(ic_df['Category'].unique())
ic_fig.update_layout(clickmode='event+select')
app.layout = html.Div([
dcc.Graph(
id='ic_figure',
figure=ic_fig)
])
## we take the 4 closest points because the 1st closest point will be the point itself
def get_n_closest_points(x0, y0, df=ic_df[['X','Y']].copy(), n=4):
"""we can save some computation time by looking for the smallest distance^2 instead of distance"""
"""distance = sqrt[(x1-x0)^2 + (y1-y0)^2]"""
"""distance^2 = [(x1-x0)^2 + (y1-y0)^2]"""
df["dist"] = (df["X"]-x0)**2 + (df["Y"]-y0)**2
## we don't return the point itself which will always be closest to itself
return df.sort_values(by="dist")[1:n][["X","Y"]].values
#app.callback(
Output('ic_figure', 'figure'),
[Input('ic_figure', 'clickData'),
Input('ic_figure', 'figure')]
)
def display_hover_data(clickData, figure):
print(clickData)
if clickData is None:
# print("nothing was clicked")
return figure
else:
hover_x, hover_y = clickData['points'][0]['x'], clickData['points'][0]['y']
closest_points = get_n_closest_points(hover_x, hover_y)
## this means that this function has ALREADY added another trace, so we reduce the number of traces down the original number
if len(figure['data']) > NUMBER_OF_TRACES:
# print(f'reducing the number of traces to {NUMBER_OF_TRACES}')
figure['data'] = figure['data'][:NUMBER_OF_TRACES]
# print(figure['data'])
new_traces = [{
'marker': {'color': 'teal', 'symbol': 'circle'},
'mode': 'markers',
'orientation': 'v',
'showlegend': False,
'x': [x],
'xaxis': 'x',
'y': [y],
'yaxis': 'y',
'type': 'scatter',
'selectedpoints': [0]
} for x,y in closest_points]
figure['data'].extend(new_traces)
# print("after\n")
# print(figure['data'])
return figure
if __name__ == '__main__':
app.run_server(debug=True)
I am attempting to use Folium to display a map of After Renovation Values for houses in a certain area. The higher the ARV, the "hotter" I want that area of the map.
I am trying to take advantage of Folium's weighted heatmap, however, random points seem to be way hotter than others despite having a lower ARV (and thus lower weighted value). When I use a lot of points for my heatmap (>1000) only one point is "hot" and the rest are cold. See image.
I am normalizing the ARV values between 0.5 and 1.5. I have tried other normalized values with no success.
In the screenshot, note that there are many points on this map with a higher ARV value and heatmap weighted value. Also there are other areas of the map with more points clustered together. So I have no idea why this one is the only one that is hot.
Below is some sample data.
import pandas as pd
import folium
from folium import Map
from folium.plugins import HeatMap
import csv_helper
# Custom function that converts a CSV with Address, Latitude, Longitude, ARV to python List
csv_list = csv_helper.csv_to_list('arvs.csv')
# Normalized min & max
new_min = 0.5
new_max = 1.5
hmap = Map(location=[41.496551, -81.65133], zoom_start=100)
# Add markers to map
for address in csv_list:
arv = int(address['ARV'])
# newvalue= (max'-min')/(max-min)*(value-min)+min'.
arv_normalized = round(float((new_max-new_min)/(500000-40000)*(arv-40000)+new_min),3)
# Show ARV value and normalized value (for heatmap) for debugging purposes
tooltip = "$" + address['ARV']
tooltip += " " + str(arv_normalized)
folium.Circle(
[address['Latitude'], address['Longitude']], popup="<i></i>", tooltip=tooltip, radius=150
).add_to(hmap)
# -------------------------------------------------
# Create heatmap with normalized ARV values
final_list = []
for address in csv_list:
arv = int(address['ARV'])
# newvalue= (max'-min')/(max-min)*(value-min)+min'.
arv_normalized = round(float((new_max-new_min)/(500000-40000)*(arv-40000)+new_min),3)
final_list.append((float(address['Latitude']), float(address['Longitude']), arv_normalized))
# ---------------------------------------
final_map = HeatMap(
final_list,
min_opacity=0.2,
radius=40,
blur=40,
)
hmap.add_child(final_map)
hmap.save('index.html')
ARV,Latitude,Longitude
80000,35.20271,-90.008334
120000,41.391633,-81.522691
130000,41.509003,-81.553549
250000,35.058779,-89.881985
160000,41.439312,-81.922154
410000,41.521241,-81.405547
350000,41.388637,-81.414451
360000,41.473301,-81.519901
264000,35.014625,-89.81703
175000,41.513541,-81.536019
410000,41.521241,-81.405547
180000,34.996242,-89.838076
110000,41.496551,-81.65133
110000,41.496551,-81.65133
140000,41.453832,-81.792491
230000,35.058779,-89.881985
150000,41.481158,-81.747563
360000,41.476918,-81.855462
130000,41.526998,-81.504134
350000,41.488054,-81.929447
850000,35.124245,-89.894052
260000,41.496551,-81.65133
400000,41.557968,-81.451966
240000,41.425264,-81.953059
110000,40.788578,-81.416775
140000,41.498209,-81.5627
120000,41.411274,-81.584893
250000,41.378911,-81.754235
250000,41.489806,-81.51235
100000,41.395767,-81.535133
40000,40.783719,-81.379159
130000,41.395311,-81.704656
140000,41.513541,-81.536019
65000,41.449614,-81.596527
160000,35.112125,-89.954644
70000,41.724602,-81.250865
120000,41.496551,-81.65133
120000,41.536174,-81.536244
75000,41.467058,-82.163095
155000,41.395311,-81.704656
500000,41.522976,-81.409499
250000,41.510947,-81.48978
165000,41.463768,-81.555838
230000,41.399833,-81.948991
270000,41.399833,-81.948991
100000,41.56134,-81.536752
260000,41.476192,-81.787702
270000,41.509563,-81.597207
145000,41.409494,-81.732268
250000,41.481919,-81.891249
130000,41.610679,-81.494706
360000,35.119919,-89.986065
370000,41.485596,-81.968291
240000,41.459678,-81.562217
480000,41.566412,-81.460469
135000,41.412794,-81.550415
390000,41.33429,-81.650159
390000,41.33429,-81.650159
90000,41.40014,-81.591994
110000,41.403025,-81.510372
250000,41.496551,-81.65133
165000,41.417272,-81.708537
230000,35.038678,-89.826112
170000,41.360592,-81.784523
230000,41.396157,-81.791135
420000,41.429342,-81.410058
310000,41.331445,-81.788
160000,41.314045,-81.831505
330000,41.347437,-81.715494
120000,41.434043,-81.713272
130000,41.389556,-81.742872
400000,41.313209,-81.827588
180000,35.029085,-89.830267
80000,41.395767,-81.535133
310000,41.313209,-81.827588
40000,35.179305,-89.987687
60000,41.460838,-81.721954
220000,35.009043,-89.803944
65000,41.517454,-81.659181
200000,41.402621,-81.666393
350000,41.475409,-81.831745
300000,41.432224,-81.941826
170000,41.405186,-81.71861
90000,41.478149,-81.649167
120000,41.442856,-81.774558
145000,41.444031,-81.813938
155000,41.424741,-81.641074
35000,41.44021,-81.640585
180000,35.048025,-89.874334
190000,41.397042,-81.792927
50000,41.569235,-81.553251
180000,41.50035,-81.569165
55000,41.518024,-81.625218
55000,41.490536,-81.76919
95000,39.821712,-86.081666
370000,41.481909,-81.936075
70000,41.607244,-81.503932
95000,39.821863,-86.081666
95000,41.44741,-81.550367
320000,41.473999,-81.847547
70000,35.152693,-89.959701
155000,41.457457,-81.552897
280000,41.48613,-81.53254
80000,35.059993,-90.089206
300000,41.432411,-81.476042
200000,41.481345,-81.713879
120000,41.496551,-81.65133
500000,41.454979,-81.933205
150000,41.496551,-81.65133
130000,41.595095,-81.532663
100000,41.433458,-81.69937
80000,35.112125,-89.954644
90000,41.431867,-81.776982
140000,41.437502,-81.719623
140000,41.437502,-81.719623
50000,41.40909,-81.727864
120000,41.446436,-81.54706
255000,41.474547,-81.520539
114000,41.447594,-81.786672
146000,41.396294,-81.719042
205000,41.496551,-81.65133
61000,41.460998,-81.664012
161000,41.526099,-81.480258
139000,41.616156,-81.516354
72000,35.261568,-90.03766
262000,41.388719,-81.655214
236000,41.42287,-81.880106
140000,41.496551,-81.65133
250000,41.481431,-81.816511
112000,41.393322,-81.568783
58000,41.474515,-81.615786
152000,35.160754,-89.941566
57000,41.45761,-81.711104
286000,41.526976,-81.625285
254000,41.502558,-81.591683
144000,41.565275,-81.522166
168672,41.496551,-81.65133
158000,41.515294,-81.480691
199000,35.145123,-89.923967
142000,41.407764,-81.705747
380000,41.515489,-81.498872
264000,41.459379,-81.546031
130000,41.59737,-81.519512
263000,41.470533,-81.856104
109000,41.616926,-81.489452
142000,41.496551,-81.65133
172000,41.468386,-81.797626
45000,41.445988,-81.637576
381000,41.479981,-81.796735
86000,41.451478,-81.570577
316000,35.141949,-89.89007
171000,41.340916,-81.67061
186000,41.527123,-81.488265
118000,41.390367,-81.857135
272000,41.493983,-81.580516
192000,41.474904,-81.790612
716000,41.497215,-81.577634
74000,41.455386,-81.644509
217000,41.474904,-81.790612
249000,41.54746,-81.464124
76000,41.401175,-81.591213
161000,35.01404,-89.842125
148000,41.458904,-81.718525
296000,41.474576,-81.510153
51000,41.496551,-81.65133
86000,41.534577,-81.563225
274000,41.331352,-82.079267
87000,41.408078,-81.550402
111000,41.495959,-81.646259
236000,41.473035,-81.924042
236000,41.473035,-81.924042
87000,41.408078,-81.550402
118000,41.453988,-81.554598
272000,41.478278,-81.71321
193000,41.389737,-81.806958
237000,41.469768,-81.839801
458000,41.461405,-81.501236
167000,41.495068,-81.550947
98000,41.461061,-81.705367
87000,41.528795,-81.620411
140000,41.416514,-81.522673
280000,35.113076,-89.939775
129000,41.462182,-81.770669
294000,41.468942,-81.818158
187000,41.496551,-81.65133
156000,41.496551,-81.65133
80000,41.538235,-81.620539
234000,41.340449,-81.724167
154000,41.539205,-81.504106
68000,41.458083,-81.60988
67000,41.598958,-81.528403
98000,41.456772,-81.586504
152000,35.197116,-89.81058
134000,41.441131,-81.72843
84000,41.520814,-81.629809
264000,41.51196,-81.578458
132000,41.457867,-81.772089
318000,41.601059,-81.544561
224000,41.305686,-81.724923