Setting Gmaps bounds in Pandas - python

I want to display a whole country, but it zooms in to a street level somewhere in the middle of the country.
I am looking for a way to set the bounds to display the full country/region requested. I know there are bound coordinates but is there a property or a call I can make in pandas/python that will set it for the figure?
Everything I have found on Google so far was related C# and not python/pandas.
#get the coordinates for google maps API
gmaps.configure(api_key=cfg.key)
#build request
params = {'key': cfg.key}
params['address'] = f"{targetLocation}"
response = requests.get(cfg.baseApiUrl, params=params)
#convert response to json
response = response.json()
northeastLatBounds = response["results"][0]["geometry"]["bounds"]["northeast"]["lat"]
northeastLngBounds = response["results"][0]["geometry"]["bounds"]["northeast"]["lng"]
southwestLatBounds = response["results"][0]["geometry"]["bounds"]["southwest"]["lat"]
southwestLngBounds = response["results"][0]["geometry"]["bounds"]["southwest"]["lng"]
coordinates = pd.DataFrame({'lat': response["results"][0]["geometry"]["location"]["lat"],
'lng': response["results"][0]["geometry"]["location"]["lng"]}, index=[0])
coordinates.loc[1] = [northeastLatBounds] + [northeastLngBounds]
coordinates.loc[2] = [southwestLatBounds] + [southwestLngBounds]
coordinates
Please note the coordinates Dataframe was for my marker layer. I thought that entering the bounds there would help, but now I have 3 markers and doesn't look clean. Any help would be great!

Well I couldn't find any property settings like we have in C# so I created a "hard coding" of the zoom level based on whether it was a country or region being searched for. Not exactly what I wanted to do but it gets the job done.

Related

is there a way to add the tooltip for every road in folium?

I'm making a map of the different bus routes in my city, I have the [lat,lon] of every station and point but the problem is that I can't seem to find a way to name the routes that I created.
Here's the code:
>df = pd.read_excel (r'Bus.xlsx')
>points= pd.DataFrame(index=np.arange(len(df)), columns=np.arange(2))
>points.columns = ["Latitude", "Longitude"]
>names = list()
>for i in range(len(df)):
> points.iloc[i,1] = df.iloc[i,3]
> points.iloc[i,0] = df.iloc[i,4]
> names.append(df.iloc[i,2])
>folium.PolyLine(points, color="red", weight=2.5, opacity=1, tooltip=names).add_to(my_map)
but when I open the map, the name that appears when I hover the mouse is the whole list as in ['xxx','yyyy','zzzz']
Any help is appreciated !!
(Just cleaning up your prep:)
df = pd.read_excel (r'Bus.xlsx')
points = df.iloc[:,[3,4]]
points.columns = ["Latitude", "Longitude"]
names = df.iloc[:,2].to_list()
This is the problematic line, as I understand it.
folium.PolyLine(points, color="red", weight=2.5, opacity=1, tooltip=names).add_to(my_map)
If I understand correctly, you're passing a table of points and drawing one polyline -- and then the tooltip for this line is your list of names. I believe you instead need to generate a list/DataFrame of pairs of points and corresponding names for route between pairs of points, and then for each pair, add that as a PolyLine to your map.

Query point data on a Google Earth Engine Image by specifying lat/long

I am trying to extract point values from a Google Earth Engine Image Collection by specifying lat/long information.
This seems to work perfectly fine when I am working with multiple images and use ee.Image.cat() to join them before I query the image. In the code example below composite = ee.Image.cat().
However, when I change composite (line 3 from the bottom) to one of the image collections (eg. chirps), it does not seem to work.
Please could someone assist me with this.
def getPropertyValue(settings):
collection = settings['collection'];
fieldName = settings['fieldName'];
dateRange = settings['dateRange'];
geoLocation = settings['geoLocation'];
scale = settings['scale'];
image = ee.ImageCollection(collection).select(fieldName).filterDate(dateRange[0], dateRange[1]).mean();
point = ee.Geometry.Point(geoLocation);
mean = image.reduceRegions(point, 'mean', scale);
valueRef = mean.select([fieldName], ['precipitation'], retainGeometry=True).getInfo();
value = valueRef[fieldName][0]['properties'][fieldName];
return value;
fieldName = 'LST_AVE';
chirps = ee.ImageCollection("JAXA/GCOM-C/L3/LAND/LST/V2").select(fieldName).filterDate('2020-01-01', '2020-02-01').mean()
point = ee.Geometry.Point([26.8206, 30.8025])
dist_stats = composite.reduceRegions(point, 'mean', 5000)
dist_stats = dist_stats.select([fieldName], [fieldName], retainGeometry=True).getInfo();
print(dist_stats['features'][0]['properties'][fieldName])
Result when using composite
14248.55
Error when replacing composite with a Google Earth Engine Image
EEException: Error in map(ID=0):
Feature.select: Selected a different number of properties (0) than names (1).
reduceRegions names the output column after the reducer, not the field that is being reduced. (Though it's more complicated when you have multiple bands and reducers).
So this:
dist_stats = dist_stats.select([fieldName], [fieldName], retainGeometry=True).getInfo();
should be changed to this
dist_stats = dist_stats.select(['mean'], [fieldName], retainGeometry=True).getInfo();

Time series on folium map

I have a dataframe that denotes events that occured in particular locations.
I am aware that folium does not allow dynamic display of the appearance of the events so I was thinking about basically iterate through the dates and save a png of each folium map created.
Unfortunately I am mentally stuck in a 2 part problem:
1) how to loop through a ranges of dates (for example one map for each month)
2) an appropriate way to save the generated images for each loop.
This is a dataframe sample for this example:
since = ['2019-07-05', '2019-07-17', '2014-06-12', '2016-03-11']
lats = [38.72572, 38.71362, 38.79263, 38.71931]
longs = [-9.13412, -9.14407, -9.40824, -9.13143]
since_map = {'since' : pd.Series(since), 'lats' : pd.Series(lats), 'longs' : pd.Series(longs)}
since_df = pd.DataFrame(since_map)
I was able to create the base map:
lat_l = 38.736946
long_l = -9.142685
base_l = folium.Map(location=[lat_l,long_l], zoom_start=12)
neigh = folium.map.FeatureGroup()
And add some of the markers to the folium map:
for lati, longi in zip(since_df.longs, since_df.lats):
neigh.add_child(folium.CircleMarker([longi, lati], radius = 2, color = 'blue', fill = True))
base_l.add_child(neigh)
I am struggling to visualize how to loop through ranges of the dates and save each file. From what I saw here:
https://github.com/python-visualization/folium/issues/35 I actually have to open the saved html and then save it as png for each image.
If you could point me to an example or documentation that could demonstrate how this can be accomplished I would be very appreciative.
If you think I am overcomplicating it or you have a better alternative to what I am thinking I have an open ear to suggestions.
Thank you for your help.

Pygal: Displaying information for each data point

I have been playing around with Pygal, creating some line graphs for a project I am working on. I currently have my y axis set to be the value recorded and the x axis being the date / time the test was conducted. However I would also like to link the serial number to each data point. At the moment when you hover on a data point you get the y value in bold and underneith that you get the date it was recorded.
Does anyone know if it is possible to link information to data points without them being an axis label?
For reference I currently have the serial numbers being added to the list: 'sn_list'.
for row in line_graph_query:
if str(row.date_time) >= start_date and str(row.date_time) <= end_date :
min_values.append(float(row.minimum_value))
max_values.append(float(row.maximum_value))
recorded_values.append(float(row.recorded_value))
sn_list.append(row.product_serial_number)
date_list.append(row.date_time)
number_of_records = number_of_records + 1
print(min_values)
print(max_values)
print(recorded_values)
distance_x_axis = math.floor(number_of_records/6)
line_chart = pygal.Line(no_data_text='No result found', style=custom_style,x_labels_major_every=distance_x_axis, x_label_rotation=20, show_minor_x_labels=False )
line_chart.title = 'Detailed Results of '+test_name+' tests of '+board_pn
line_chart.x_labels = map(str,date_list)
line_chart.add('Minimum', min_values)
line_chart.add('Maximum', max_values)
line_chart.add('Recorded', recorded_values)
graph_render.append(line_chart.render_data_uri())
graphs_to_render[test_name] = graph_render[-1]
You can set the tooltip to any text you like by providing your data as dicts (see the documentation here). Each value should be represented by a dict that has at least a value attribute, this is the same value that you were providing to the chart directly. There are then a number of other attributes you can set, amongst them label.
You should be able to get the tooltips you want by changing the three lines that append data in your if structure:
min_values.append({"value": float(row.minimum_value),
"label": row.product_serial_number})
max_values.append({"value": float(row.maximum_value),
"label": row.product_serial_number})
recorded_values.append({"value": float(row.recorded_value),
"label": row.product_serial_number})
Unless you are using it somewhere else this also means that you have no need of the sn_list.

Bokeh Plotting 'Out of range float values are not JSON compliant' Issue

I try to build a heat map by using bokeh. However I keep getting the same error. I'll include both my code and error below, please help me out!
I assumed that the error is mainly about Nan's in my data, so I've added necessary if statements to the code to make sure that this issue is addressed. Even tried to fill any possible Na's with zero in the following lists: 'user','module','ratio','color', and 'alpha'. However none of these changes helped.
colors = ['#ff0000','#ff1919','#ff4c4c','#ff7f7f','#99cc99','#7fbf7f','#4ca64c','#329932','#008000'] sorted_userlist = list(total_checks_sorted.index) user = [] module = [] ratio = [] color = [] alpha = []
for m_id in ol_module_ids:
pset = m_id.split('/')[-1]
col_name1 = m_id + '_ratio'
col_name2 = m_id + '_total'
min_checks = min(check_matrix[col_name2].values)
max_checks = max(check_matrix[col_name2].values)
for i, u in enumerate(sorted_userlist):
module.append(pset)
user.append(str(i+1))
ratio_value = check_matrix[col_name1][u]
ratio.append(ratio_value)
al= math.sqrt((check_matrix[col_name2][u]-min_checks+0.0001)/float(max_checks))
if ratio_value>0.16:
al = min(al*100,1)
alpha.append(al)
if np.isnan(ratio_value):
color.append(colors[0])
else:
color.append(colors[int(ratio_value*8)])
#fill NAs in source lists with zeroes pd.Series(ratio).fillna(0).tolist()
col_source = ColumnDataSource(data = dict(module = module, user = user, color=color, alpha=alpha, ratio = ratio))
#source = source.fillna('')
#TOOLS = "resize,hover,save,pan,box_zoom,wheel_zoom" TOOLS = "reset,hover,save,pan,box_zoom,wheel_zoom"
p=figure(title="Ratio of Correct Checks Each Student Each Online Homework Problem",
x_range=pset,
#y_range = list(reversed(sorted_userlist)),
y_range=list(reversed(list(map(str, range(1,475))))),
x_axis_location="above", plot_width=900, plot_height=4000,
toolbar_location="left", tools=TOOLS)
#axis_line_color = None)
#outline_line_color = None)#
p.rect("module", "user", 1, 1, source=col_source,
color="color", alpha = 'alpha', line_color=None)
show(p)
NaN values are not JSON serializable (this is a glaring deficiency in the JSON standard). You mentioned there are NaN values in the ratio list, which you are putting in the ColumnDataSource here:
col_source = ColumnDataSource(data=dict(..., ratio=ratio))
Since it is in the CDS, Bokeh will try to serialize it, resulting in the error. You have two options:
If you don't actually need the numeric ratio values in the plot for some reason (e.g. to drive a hover tool or custom mapper or something), then just leave it out of the data source.
If you do need to send the ratio values, then you must put the data into a NumPy array. Bokeh serializes NumPy arrays using a different, non-JSON approach, so it is then possible to send NaNs successfully.

Categories

Resources