Matplotlib Python Stealing Screen Focus - macos

my code is taking serial data from an arduino, processing it, and then plotting it. I am using matplotlib as the graphics interface. Every time it 'draws' though it forces attention to it, and a user won't be able to look at anything besides that. What is the best way to get this to stop? (The code works fine except for the stealing focus). I tried to use the matplotlib.use('Agg') method after reading that on another post, but it did not work. (Using a MAC OS X).
The Code shown below is a super simple graph of updating data, with which I have the same problem. I'm not showing my code because it is not copy-pastable without the right inputs
Here is my code:
import matplotlib
from matplotlib import *
from pylab import *
# import math
x=[]
y=[]
def function(iteration):
xValue=iteration#Assigns current x value
yValue=(1./iteration)*34#Assigns current y value
x.extend([xValue]) #adds the current x value to the x list
y.extend([yValue]) #adds the current y value to the y list
clf() #clears the plot
plot(x,y,color='green') #tells the plot what to do
draw() #forces a draw
def main():
for i in range(1,25): #run my function 25 times (24 I think actually)
function(i)
pause(.1)
main()

Have you tried using the interactive mode of matplotlib?
You can switch it on using ion() (see Documentation)
If you use interactive mode you do not need to call draw() but you might need to clear your figures using clf() depending on your desired output

I find that using the Tkagg backend works
import matplotlib
matplotlib.use('Tkagg')
credit to 457290092

Related

Issue with xarray.open_raterio() img file and multiprocessing Pool

I am trying to use mutliprocessing Pool.map() to speed up my code. In the function where I have computation occurring for each process I reference an xarray.DataArray that was opened using xarray.open_rasterio(). However, I receive errors similar to this:
rasterio.errors.RasterioIOError: Read or write failed. /net/home_stu/cfite/data/CDL/2019/2019_30m_cdls.img, band 1: IReadBlock failed at X offset 190, Y offset 115: Unable to open external data file: /net/home_stu/cfite/data/CDL/2019/
I assume this is some issue related to the same file being referenced simultaneously while another worker is opening it too? I use DataArray.sel() to select small portions of the raster grid that I work with since the entire .img file is way to big to load all at once. I have tried opening the .img file in the main code and then just referencing to it in my function, and I've tried opening/closing it in the function that is being passed to Pool.map() - and receive errors like this regardless. Is my file corrupted, or will I just not be able to work with this file using multiprocessing Pool? I am very new to working with multiprocessing, so any advice is appreciated. Here is an example of my code:
import pandas as pd
import xarray as xr
import numpy as np
from multiprocessing import Pool
def select_grid(x,y):
ds = xr.open_rasterio('myrasterfile.img') #opening large file with xarray
grid = ds.sel(x=slice(x,x+50), y=slice(y,y+50))
ds.close()
return grid
def myfunction(row):
x = row.x
y = row.y
mygrid = select_grid(x,y)
my_calculation = mygrid.sum() #example calculation, but really I am doing multiple calculations
my_calculation.to_csv('filename.csv')
with Pool(30) as p:
p.map(myfunction, list_of_df_rows)

How to use kde_kws parameters for seaborn.histplot()?

I am trying to use sns.histplot() instead of sns.distplot() since I got the following message in colab:
FutureWarning: distplot is a deprecated function and will be removed
in a future version. Please adapt your code to use either displot (a
figure-level function with similar flexibility) or histplot (an axes-level function for histograms).
Code:
import pandas as pd
import seaborn as sns
df = sns.load_dataset('tips')
sns.histplot(df['tip'], kde=True, kde_kws={'fill' : True});
I got an error when passing kde_kws parameters inside sns.histplot():
TypeError: init() got an unexpected keyword argument 'fill'
From the documentation kde_kws= is intended to pass arguments "that control the KDE computation, as in kdeplot()." It is not entirely explicit which arguments those are, but they seem to be the ones like bw_method= and bw_adjust= that change the way the KDE is computed, rather than displayed. If you want to change the appearance of the KDE plot, the you can use line_kws=, but, as the name implies, the KDE is represented only by a line and therefore cannot be filled.
If you want both a histogram and a filled KDE, you need to combine histplot() and kdeplot() on the same axes
sns.histplot(df['tip'], stat='density')
sns.kdeplot(df['tip'], fill=True)

How to get similar results to pydub.silence.detect_nonsilent() using librosa.effects.split()?

I love pydub. It is simple to understand. But when it comes to detecting non-silent chunks, librosa seems much faster. So I want to try using librosa in a project to speed my code up.
So far, I have been using pydub like this (segment is an AudioSegment):
thresh = segment.dBFS - (segment.max_dBFS - segment.dBFS)
non_silent_ranges = pydub.silence.detect_nonsilent(segment, min_silence_len=1000, silence_thresh=thresh)
The thresh formula works mostly well, and when it does not, moving it a 5 or so dbs up or down does the trick.
Using librosa, I am trying this (y is a numpy array loaded with librosa.load(), with an sr of 22050)
non_silent_ranges = librosa.effects.split(y, frame_length=sr, top_db=mistery)
To get similar results to pydub I tried setting mistery to the following:
mistery = y.mean() - (y.max() - y.mean())
and the same after converting y to dbs:
ydbs = librosa.amplitude_to_db(y)
mistery = ydbs.mean() - (ydbs.max() - ydbs.mean())
In both cases, the results are very different from what get from pydub.
I have no background in audio processing and although I read about rms, dbFS, etc, I just don't get it--I guess I am getting old:)
Could somebody point me in the right direction? What would be the equivalent of my pydub solution in librosa? Or at least, explain to me how to get the max_dBFS and dBFS values of pydub in librosa (I am aware of how to convert and AudioSegment to the equivalent librosa numpy array thanks to the excellent answer here)?
max_dBFS is always 0 by it's nature. dBFS is how much "quieter" the sound is than the max possible signal.
I suspect another part of your issue is that ydbs.max() is the maximum value among data in ydbs, not the maximum possible value that can be stored (i.e., the highest integer or float possible)
Another difference from pydub is your use of ydbs.mean(), pydub uses RMS when computing dBFS.
You can convert ydbs.mean() to dbfs like so:
from numpy import mean, sqrt, square, iinfo
max_sample_value = iinfo(ydbs.dtype).max
ydbs_rms = sqrt(mean(square(ydbs))
ydbs_dbfs = 20 * log(ydbs_rms) / max_sample_value, 10)

Raspberry timelapse movie on the fly

I have a Raspberry on which I want to create a timelapse movie.
All examples I see in the internet FIRST save a bunch of images and THEN converts them into a movie all at once.
I want to create a movie over a long period of time so I can't save thousands of images. What I need is a tool that adds an image to a movie right after the image is captured.
Is there a chance to do that?
There's a flaw in your logic, I think - by adding each image to the movie, you would necessarily be adding a full-frame, rather than only a diff frame. This will result in higher quality, sure - but it will also not save you anything in terms of space as compared to saving the entire image. The space savings you see in adding things to movies is all about that diff, rather than storing a full frame.
Doing a partial diff with check-frames at increments might work, but I'm not sure what format you're targeting, nor what codexes would be needed in order to arbitrarily tack on either a diff frame or a full frame, depending on some external condition - encoding usually takes place as a series of operations rather than singly.
An answer but it isn't finished!
I need your help making this perfect!
Running in python2
import os, cv2
from picamera import PiCamera
from picamera.array import PiRGBArray
from datetime import datetime
from time import sleep
now = datetime.now()
x = now.strftime("%Y")+"-"+now.strftime("%m")+"-"+now.strftime("%d")+"-"+now.strftime("%H")+"-"+now.strftime("%M") #string of dateandtimestart
def main():
imagenum = 100 #how many images
period = 1 #seconds between images
os.chdir ("/home/pi/t_lapse")
os.mkdir(x)
os.chdir(x)
filename = x + ".avi"
camera = PiCamera()
camera.resolution=(1920,1088)
camera.vflip = True
camera.hflip = True
camera.color_effects = (128,128) #makes a black and white image for IR camera
sleep(0.1)
out = cv2.VideoWriter(filename, cv2.cv.CV_FOURCC(*'XVID'), 30, (1920,1088))
for c in range(imagenum):
with PiRGBArray(camera, size=(1920,1088)) as output:
camera.capture(output, 'bgr')
imagec = output.array
out.write(imagec)
output.truncate(0) #trying to get more than 300mb files..
pass
sleep(period-0.5)
camera.close()
out.release()
if __name__ == '__main__':
main()
I've got this configured with with a few buttons and an OLED to select time spacing and frame numbers displayed on a OLED (code not shown above for simplicity but it is also here: https://github.com/gchennell/RPi-PiLapse )
This doesn't make videos larger than 366Mb which is some sort of limit I've reached and I don't know why - if anyone has a good suggestion I would appreciate it

What is the corret syntax for using max function

Still using bloody OpenOffice Writer to customize my sale_order.rml report.
In my sale order I have 6 order lines with 6 different lead time to delivery. I need to show the maximum out of the six values.
After many attempt I have abandoned using the reduce function as it works erratically or not at all most of the time. I have never seen anything like this.
So I thought I'd give a try using max encapsulating a loop such as:
[[ max(repeatIn(so.order_line.delay,'d')) ]]
My maximum lead time being 20, I would expect to see 20 (yes well that would be too easy, wouldn't it!).
It returns
{'d': 20.0}
At least it contains the value I am after.
But; if I try and manipulate this result, it disappears altogether.
I have tried:
int(re.findall(r'[0-9]+', max(repeatIn(so.order_line.delay,'d')))[0])
which works great from the python window, but returns absolutely nothing in OpenERP.
I import the re from my sale_order.py file, which I have recompiled into sale_order.pyo:
import time
import re
from datetime import datetime, timedelta
from report import report_sxw
class order(report_sxw.rml_parse):
def __init__(self, cr, uid, name, context=None):
super(order, self).__init__(cr, uid, name, context=context)
self.localcontext.update({
'time': time,
'datetime': datetime,
'timedelta': timedelta,
're': re,
})
I have of course restarted the server many times. My test install sits on windows.
So can anyone tell me what I am doing wrong, because I can make it work from Python but not from OpenOffice Writer!
Thanks for your help!
EDIT 1:
The format
{'d': 20.0}
is, according to python, a dictionary. Still in Python, to extract the integer from a dictionary it is possible to do it like so:
>>> dict={'d': 20.0}
>>> print(dict['d'])
20.0
But how can I transpose this to OpenERP writer???
I have manage to get the result I wanted by importing functools and declaring the reduce function within the parameters of the sale_order.py file.
I then simply used a combination of reduce and max function and it works exactly as expected.
The correct syntax is as follow:
repeatIn(objects,'o')
reduce(lambda x, y: max(x, y.delay), o.order_line, 0)
Nothing else is required.
Enjoy!

Resources