Only display marker at TimeStamp using Folium TimestampedGeoJson - python-3.x

I am plotting ground tracks of a satellite using Folium's TimestampGeoJson plugin. I am able to plot the animated markers, but would like to only display the marker at timestamp. I want the previous markers to disappear, and only have one marker shown on the map at a time, to create the illusion of the satellite moving around the map.
Here is the code I use to generate the map:
import folium
import webbrowser
from folium.plugins import TimestampedGeoJson
def generate_map(latlon_list, geojson_data):
my_map = folium.Map(location=[0,0], height=1000, width=1000, zoom_start=2,
min_zoom=2, max_zoom=12, max_bounds=True, no_wrap=True)
map_name = "folium_1000_1000_map.html"
tgj = TimestampedGeoJson(geojson_data, period="PT1M", add_last_point=False)
my_map.add_child(tgj)
This generates the following:
I want the animation to only display one marker at a time. Here is a ref to a similar question I have found, but none of the answers mentioned there have the effect I want.
Thanks.

And the answer lies in the referenced question, i just added:
tgj = TimestampedGeoJson(satellite["geojson_data"], period="PT1M", duration="PT1M", add_last_point=False)
To my TimestampedGeoJson object, and voila ! Only markers at timestamp will be displayed now. The important option here is the duration one.

Related

OpenCV - ArUco : detectMarkers failed identified some markers in a photos

I have pictures containing ArUco markers but I am unable to detect all of them with the detectMarkers function. Actually, I have many pictures : in some of them I can detect all the markers, in others I cannot and I don't really understand why.
I thought it was because of the quality of the photo, but it seems to be not so simple. Here's an example of my code :
import cv2
import matplotlib.pyplot as plt
from cv2 import aruco
aruco_dict = aruco.Dictionary_get(aruco.DICT_4X4_1000)
inputfile = 'EOS-1D-X-Mark-II_1201-ConvertImage.jpg'
frame = cv2.imread(inputfile)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
parameters = aruco.DetectorParameters_create()
corners, ids, rejectedImgPoints = aruco.detectMarkers(frame, aruco_dict, parameters=parameters)
frame_markers = aruco.drawDetectedMarkers(frame.copy(),rejectedImgPoints)
plt.figure(figsize=(20,10))
plt.imshow(frame_markers)
for i in range(len(ids)):
c = corners[i][0]
plt.plot([c[:, 0].mean()], [c[:, 1].mean()], "o", label = "id={0}".format(ids[i]))
plt.legend()
plt.show()
In this picture, 1 marker is not detected and I don't understand why.
I tried to tune the parameters of detectMarkers function manually with an interactive method thanks to jupyter notebook. There are many parameters and I found nothing that really helped me, except in some photos the reduction of polygonalApproxAccuracyRate.
The photo is orginally in 5472 x 3648 pixels but the one I send in this post is 2189 x 1459 pixels. Note that it doesn't work with the better resolution neither. Actually, I found in some photos that reducing the resolution help to detect the markers ... It's a contradiction but I think this is because the default parameters of the function are not adapted to my pictures, but I found no solution when tuning the parameters.
Another idea is to use the refineDetectMarkers function after calling detectMarkers. It uses the candidates that were found in detectMarkers but failed to be identified, and try to refine their identification. However, as far as I understood, I need to know where my markers should be in the picture and put it in refineDetectMarkers (as a board). In my situation, I don't know where the markers should be, otherwise I wouldn't take photos. The photos are used to observe precisely the evolution of their positions.
I am interested in any ideas you may have, thanks for reading !

Photutils DAOPhot Not Fitting stars well?

I recently ran across the PhotUtils package and am trying to use it to perform PSF Photometry on some images I have. However, when I try to run the code, I get very strange results. When I plot the image generated by get_residual_image(), the stars are not removed well. Some sample images are shown below.
The first image has sigma set to 2.05, as it is in one of the sample programs in the PhotUtils documentation:
However, the stars only appear to be removed in their center.
The second image has sigma set to 5.0. This one is especially strange. Some stars are way over-removed, some are under removed, some black squares are added to the image, etc.
Here is my code:
import photutils
from photutils.psf import DAOPhotPSFPhotometry as DAOP
from photutils.psf import IntegratedGaussianPRF as PRF
from photutils.background import MMMBackground
bkg = MMMBackground()
background = 2.5*bkg(img)
gaussian_prf = PRF(sigma=5.0)
gaussian_prf.sigma.fixed = False
photTester = DAOP(8,background,5,gaussian_prf,31)
photResults = photTester(imgStars)
finalImg = photTester.get_residual_image()
After this, I simply plot the original and final image in MatPlotLib. I use a greyscale colormap. The reason that the left images appear slightly darker is that they use a different color scaling.
Perhaps I have set one of the parameters incorrectly?
Could someone help me out with this? Thank you!
Looking at the residual image instantly told me that the background subtraction might be wrong. I could reproduce the result and wondered, if MMMBackground did not do the job correctly.
After taking a closer look at the documentation, Getting startet with Photutils finally gave the essential hint:
image -= np.median(image)

gmplot Marker does not work after it marks 256 points

I am trying to mark a bunch of points on the map with gmplot and observed that after a certain point it stops marking and wipes out all the previously marked points. I debugged the gmplot.py module and saw that when the length of points array exceeds 256 this is happening without giving any error and warning.
self.points = [] on gmplot.py
Since I am very new to Python and OOPs concept, is there a way to override this and mark more than 256 points?
Are you using gmplot.GoogleMapPlotter.Scatter or gmplot.GoogleMapPlotter.Marker. I used either and was able to get 465 points for a project that I was working on. Is it possible it is an API key issue for you?
partial snippet of my code
import gmplot
import pandas as pd
# df is the database with Lat, Lon and formataddress columns
# change to list, not sure you need to do this. I think you can cycle through
# directly using iterrows. I have not tried that though
latcollection=df['Lat'].tolist()
loncollection=df['Lon'].tolist()
addcollection=df['formataddress'].tolist()
# center map with the first co-ordinates
gmaps2 = gmplot.GoogleMapPlotter(latcollection[0],loncollection[0],13,apikey='yourKey')
for i in range(len(latcollection)):
gmaps2.marker(latcollection[i],loncollection[i],color='#FF0000',c=None,title=str(i)+' '+ addcollection[i])
gmaps2.draw(newdir + r'\laplot_marker_full.html')
I could hover over the 465th point since I knew approximately where it was and I was able to get the title with str(464) <formataddress(464)>, since my array is indexed from 0
Make sure you check the GitHub site to modify your gmplot file, in case you are working with windows.

How to retrieve the bounding box of a scalebar from a AnchoredSizeBar from Matplotlib

I am facing serious difficulties in retrieving the bounding box of a mpl_toolkits.axes_grid1.anchored_artists "AnchoredSizeBar" object.
So far, all I found was how to insert (create) an AnchoredSizeBar into my figure. But I can't retrieve its position. A relative position in respect to its given axes would also be welcome.
Ultimately, I would like to make a AnchoredSizeBar as Behnam asks in1. But in order to do so, I would need to create a series of AnchoredSizeBars all contiguous one to another in the figure. In order to do so, I would need a function to retrieve their relative positions and apply those into the creation of the other AnchoredSizeBars, creating finally a full scalebar.
This subject is related to other links presented below:
1) How to insert scale bar in a map in matplotlib
2) Add fill_bar argument to AnchoredSizeBar
Here is a snippet code of a desired API for AnchoredSizeBar object extent retrieval.
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar
fig, ax = plt.subplots(figsize=(3, 3))
bar0 = AnchoredSizeBar(ax.transData, 0.3, 'unfilled', loc=3, frameon=False,
size_vertical=0.05, fill_bar=False)
ax.add_artist(bar0)
bar0_extent = bar0.get_extent()
fig.show()
I thank you for your time, sincerely yours,
Philipe Leal
To get the extent you can pass in ax.figure.canvas.renderer where ax is the axes to which the object has been added to:
bar0_extent = bar0.get_extent(ax.figure.canvas.renderer)
But I second #ImportanceOfBeingErnest's suggestion for your particular use case. The doc-string for AnchoredSizeBar suggests that methods:
Docstring: An offset box placed according to the legend location
loc. AnchoredOffsetbox has a single child. When multiple children is
needed, use other OffsetBox class to enclose them. By default, the
offset box is anchored against its parent axes. You may explicitly
specify the bbox_to_anchor.
Hope this helps.

Python3x + MatPlotLib - Updating a chart?

I am new to both the python and matplotlib languages and working on something for my husband.
I hope you guys can help me out.
I would like to pull in a file using Open, read it, and update a graph with it's values.
Sounds easy enough right? Not so much in practice.
Here is what I have so far to open and chart the file. This works fine as it is to chart the file 1 time.
import matplotlib.pyplot as plt
fileopen = open('.../plotresults.txt', 'r').read()
fileopen = eval(fileopen) ##because the file contains a dict and security is not an issue.
print(fileopen) ## So I can see it working
for key,value in fileopen.items():
plot1 = value
plt.plot(plot1, label=str(key))
plt.legend()
plt.show()
Now I would like to animate the chart or update it so that I can see changes to the data. I have tried to use matplotlib's animation feature but it is advanced beyond my current knowledge.
Is there a simple way to update this chart, say every 5 minutes?
Note:
I tried using Schedule but it breaks the program (maybe a conflict between schedule and having matplotlib figures open??).
Any help would be deeply appreciated.
Unfortunately you will just waste time trying to get a clean solution without either using matplotlib's animation feature or using the matplotlib OO interface.
As a dirty hack you can use the following:
from threading import Timer
from matplotlib import pyplot as plt
import numpy
# Your data generating code here
def get_data():
data = numpy.random.random(100)
label = str(data[0]) # dummy label
return data, label
def update():
print('update')
plt.clf()
data, label = get_data()
plt.plot(data, label=label)
plt.legend()
plt.draw()
t = Timer(0.5, update) # restart update in 0.5 seconds
t.start()
update()
plt.show()
It spins off however a second thread by Timer. So to kill the script, you have to hit Ctrl-C twice on the console.
I myself would be interested if there is a cleaner way to do this in this simple manner in the confines of the pyplot machinery.
Edits in italic.

Resources