ERROR WHEN SHOWING VALUE OF VARIABLES FROM 2 PANELS - python-3.x

i have 2 panels when i extract values of variables
what i need to do is to show all value from 3 panels in the same panel ..
the panel is for showing all information about files in the 3 panels
i try to add in this panels of value of variables from 3 panels to showing in this panel but i get error like :
Traceback (most recent call last):
File "C:\Users\majdoulina\Anaconda3\lib\site-packages\matplotlib\cbook\__init__.py", line 215, in process
func(*args, **kwargs)
File "D:\DATA\app6.py", line 450, in on_press
self.GrandParent.right.bottom.bottom.top.Update(x1,y1,list_var3,lon,lat)
TypeError: Update() missing 1 required positional argument: 'list_var4'
what i need to do is to show value of variable from 3 panels in this panel this is part of code wher i have error :
class MiddlePanelTop(wx.Panel):
def __init__(self, parent):
super().__init__(parent, name="MiddleTop", style = wx.SUNKEN_BORDER,size = (500,200))
self.SetBackgroundColour('black')
def Update(self,zoom_axes):
#Load axis values of the selected rectangle
#zoom_axes=parent.zoom_axes
#duplicate the plot from the main panel
self.figure = Figure(figsize =(5,4))
self.canvas = FigureCanvas(self, -1, self.figure)
self.axes = self.figure.add_subplot(111)
self.figure.subplots_adjust(left=0.009,right=0.99,bottom=0.09,top=0.99)
#Apply axis of drawn rectangle to the plot
self.axes.axis(zoom_axes)
path=file_names
nc = netCDF4.Dataset(file_names)
fic1='D:/DATA/latlon_+000.0_globe.nc'
fic2='D:/DATA/landsea_+000.0.h5'
hdf=h5py.File(fic2,'r')
landsea=hdf['dataset'][:]
var = nc.variables.keys()
list_var3 = [nc.variables['VIS006'],nc.variables['VIS008'],nc.variables['IR_120'],nc.variables['IR_108'],nc.variables['IR_087'],
nc.variables['IR_134'],nc.variables['IR_039'],nc.variables['WV_073'],nc.variables['WV_062'],nc.variables['IR_097']]
print("update2")
data_list = ['VIS006','VIS008','IR_120','IR_108','IR_087','IR_134','IR_039','WV_073','WV_062','IR_097']
list_var3 = [nc.variables[f] for f in data_list]
nc1 = netCDF4.Dataset(fic1,'r')
lons = nc1.variables['lon'][:]
lats = nc1.variables['lat'][:]
self.lons = lons[:]
self.lats = lats[:]
print("Option chosen update")
global index
print("index=",index)
self.list_var3 = list_var3[index][:]
self.axes.imshow(self.list_var3,cmap=plt.cm.gist_yarg)
self.clevs=np.arange(0,3,1)
self.axes.contour(landsea,self.clevs,extend="max",colors='y')
self.axes.get_xaxis().set_visible(False)
self.axes.get_yaxis().set_visible(False)
self.canvas.mpl_connect('button_press_event', self.on_press)
global x1,y1
self.rect = patches.Rectangle((x1, y1), 40, 40,edgecolor='g', alpha=1, fill=None, label='Label')
self.axes.add_patch(self.rect)
self.figure.add_axes(self.axes)
'self.figure.show()'
self.axes.plot()
#add_artist(t)
def on_press(self, click):
global x1, y1
x1, y1 = click.xdata, click.ydata
list_var3 = self.list_var3[int(y1),int(x1)]
lon = self.lons[int(y1),int(x1)]
lat = self.lats[int(y1),int(x1)]
self.GrandParent.right.bottom.bottom.top.Update(x1,y1,list_var3,lon,lat)
zx1 = x1 - 20
zy1 = y1 - 20
zx2 = x1 + 20
zy2 = y1 + 20
self.rect.set_x(x1 - 20) #Move the rectangle and centre it on the X click point
self.rect.set_y(y1 - 20) #Move the rectangle and centre it on the Y click point
x1=x1-20
y1=y1-20
self.axes.plot()
self.canvas.draw()
self.zoom_axes=[zx1,zx2,zy1,zy2]
global zoom
global zoom2
zoom2=self.zoom_axes
self.GrandParent.right.bottom.top.left.Update(self.zoom_axes)
'self.GrandParent.middle.top.Update(zoom)'
self.GrandParent.middle.bottom.Update(zoom)
self.GrandParent.right.top.Update(zoom)
self.GrandParent.right.bottom.top.right.Update(self.zoom_axes)
self.GrandParent.right.bottom.top.left.Update(self.zoom_axes)
self.GrandParent.right.bottom.top.middle.Update(self.zoom_axes)
class MiddlePanelBottom(wx.Panel):
def __init__(self, parent):
super().__init__(parent, name="MiddleBottom", style = wx.SUNKEN_BORDER,size = (300,200))
self.SetBackgroundColour('black')
def Update(self,zoom_axes):
#Load axis values of the selected rectangle
#zoom_axes=parent.zoom_axes
#duplicate the plot from the main panel
self.figure = Figure(figsize =(5,4))
self.canvas = FigureCanvas(self, -1, self.figure)
self.axes = self.figure.add_subplot(111)
self.figure.subplots_adjust(left=0.009,right=0.99,bottom=0.1,top=0.98)
#Apply axis of drawn rectangle to the plot
self.axes.axis(zoom_axes)
path=file_names
nc = netCDF4.Dataset(file_names)
fic1='D:/DATA/latlon_+000.0_globe.nc'
var = nc.variables.keys()
list_var4 = [nc.variables['VIS006'],nc.variables['VIS008'],nc.variables['IR_120'],nc.variables['IR_108'],nc.variables['IR_087'],
nc.variables['IR_134'],nc.variables['IR_039'],nc.variables['WV_073'],nc.variables['WV_062'],nc.variables['IR_097']]
print("update3")
data_list = ['VIS006','VIS008','IR_120','IR_108','IR_087','IR_134','IR_039','WV_073','WV_062','IR_097']
list_var4 = [nc.variables[f] for f in data_list][:]
nc1 = netCDF4.Dataset(fic1,'r')
lons = nc1.variables['lon'][:]
lats = nc1.variables['lat'][:]
self.lons = lons[:]
self.lats = lats[:]
print("Option chosen update")
global index
print("index=",index)
self.list_var4 = list_var4[index][:]
self.axes.imshow(self.list_var4,origin ='lower')
self.axes.get_xaxis().set_visible(False)
self.axes.get_yaxis().set_visible(False)
self.canvas.mpl_connect('button_press_event', self.on_press)
global x1,y1
self.rect = patches.Rectangle((x1, y1), 40, 40,edgecolor='g', alpha=1, fill=None, label='Label')
self.axes.add_patch(self.rect)
self.axes.plot()
def on_press(self, click):
global x1, y1
x1, y1 = click.xdata, click.ydata
list_var4 = self.list_var4[int(y1),int(x1)]
lon = self.lons[int(y1),int(x1)]
lat = self.lats[int(y1),int(x1)]
self.GrandParent.right.bottom.bottom.top.Update(list_var4)
zx1 = x1 - 20
zy1 = y1 - 20
zx2 = x1 + 20
zy2 = y1 + 20
self.rect.set_x(x1 - 20 ) #Move the rectangle and centre it on the X click point
self.rect.set_y(y1 - 20 ) #Move the rectangle and centre it on the Y click point
x1=x1-20
y1=y1-20
self.axes.plot()
self.canvas.draw()
self.zoom_axes=[zx1,zx2,zy1,zy2]
global zoom
global zoom2
zoom=self.zoom_axes
self.GrandParent.right.bottom.top.left.Update(self.zoom_axes)
self.GrandParent.middle.top.Update(zoom)
'self.GrandParent.middle.bottom.Update(zoom)'
self.GrandParent.right.top.Update(zoom)
self.GrandParent.right.bottom.top.right.Update(self.zoom_axes)
self.GrandParent.right.bottom.top.left.Update(self.zoom_axes)
self.GrandParent.right.bottom.top.middle.Update(self.zoom_axes)
class RightPanelBottomBottomTop(wx.Panel):
def __init__(self,parent):
super().__init__(parent,style = wx.SUNKEN_BORDER)
self.text_ctrl = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE|wx.BORDER_SUNKEN|wx.TE_READONLY|wx.TE_RICH2, size=(700,30))
self.text_ctrl.SetBackgroundColour('cyan')
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.text_ctrl,0)
self.SetSizer(sizer)
def Update(self,x1,y1,list_var3,lon,lat,list_var4):
update_str = "X :"+str(int(x1)) + " " +"Y :"+str(int(y1)) + " "+ "var3 :"+str(int(list_var3))+" "+"Lon : "+str(int(lon))+" "+"Lat :"+str(int(lat))+ "var4 :"+str(int(list_var4))
self.text_ctrl.SetValue(update_str)
panel where i showing information is : class RightPanelBottomBottomTop
thank you

I suspect that you have more than one problem with that code.
The error tells you exactly what the problem is i.e.
missing 1 required positional argument: 'list_var4'
You call class RightPanelBottomBottomTop's Update function with 2 different sets of parameters
self.GrandParent.right.bottom.bottom.top.Update(list_var4)
and
self.GrandParent.right.bottom.bottom.top.Update(x1,y1,list_var3,lon,lat)
Neither of those is correct!
It is defined as:
def Update(self,x1,y1,list_var3,lon,lat,list_var4):

I find solution myself but i still have some problem with value i visualize like
i can show name for variables from 2 panel just the first and x y lat lon and name of variable for other panels but still can't show value from var2 and var3 just for var1 !

Related

Bounding box detection is off

Hi -
I am playing around with tensor flows object detection for raspberry pi. https://github.com/tensorflow/examples/blob/master/lite/examples/object_detection/raspberry_pi/README.md
My problem is, Tensorflow detects the object correctly. However, incorrectly gives coordinates to the detected object. It's driving me bananas. I can't figure it out.
PFB:
def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
'--model', help='File path of .tflite file.', required=True)
parser.add_argument(
'--labels', help='File path of labels file.', required=True)
parser.add_argument(
'--threshold',
help='Score threshold for detected objects.',
required=False,
type=float,
default=0.4)
args = parser.parse_args()
np.set_printoptions(threshold=sys.maxsize)
labels = load_labels(args.labels)
interpreter = Interpreter(args.model)
interpreter.allocate_tensors()
_, input_height, input_width, _ = interpreter.get_input_details()[0]['shape']
with picamera.PiCamera(
resolution=(CAMERA_WIDTH, CAMERA_HEIGHT), framerate=30) as camera:
camera.rotation = 180
camera.start_preview()
try:
print("works!!!")
stream = io.BytesIO()
annotator = Annotator(camera)
count = 0
for _ in camera.capture_continuous(
stream, format='jpeg', use_video_port=True):
stream.seek(0)
image = Image.open(stream).convert('RGB').resize(
(input_width, input_height), Image.ANTIALIAS)
#image = image.rotate(180, PIL.Image.NEAREST, expand = 1)
start_time = time.monotonic()
results = detect_objects(interpreter, image, args.threshold)
elapsed_ms = (time.monotonic() - start_time) * 1000
open_cv_image = np.array(image)
distance = us.get_distance()
print(distance)
print("*********************NUM PY DATA **********************")
print(results)
#print(type(image))
filename = "geeks"
filename += str(count)
filename += ".png"
annotator.clear()
print("Annotating!!")
print(annotator)
annotate_objects(annotator,results,labels,open_cv_image, count)
annotator.text([5, 0], '%.1fms' % (elapsed_ms))
annotator.update()
print(annotator)
count += 1
stream.seek(0)
stream.truncate()
finally:
camera.stop_preview()
if __name__ == '__main__':
main()
def annotate_objects(annotator, results, labels, npcv, count):
"""Draws the bounding box and label for each object in the results."""
window_name = 'Image'
image = npcv
filename="image"
filename+=str(count)
filename+=".jpg"
for obj in results:
# Convert the bounding box figures from relative coordinates
# to absolute coordinates based on the original resolution
ymin, xmin, ymax, xmax = obj['bounding_box']
xmin = int(xmin * CAMERA_WIDTH)
xmax = int(xmax * CAMERA_WIDTH)
ymin = int(ymin * CAMERA_HEIGHT)
ymax = int(ymax * CAMERA_HEIGHT)
if obj['score'] >= 0.60:
start_point = (xmin,ymin)
end_point = (xmax,ymax)
color = (255, 0, 0)
thickness = 20
image = cv2.rectangle(image, start_point, end_point, color, thickness)
font = cv2.FONT_HERSHEY_SIMPLEX
org = (xmin, ymin)
fontScale = 0.5
color = (255, 0, 0)
text = labels[obj['class_id']]
thickness = 2
image = cv2.putText(image, text , org, font,
fontScale, color, thickness, cv2.LINE_AA)
annotator.bounding_box([xmin, ymin, xmax, ymax])
annotator.text([xmin, ymin],
'%s\n%.2f' % (labels[obj['class_id']], obj['score']))
print(labels[obj['class_id']], obj['score'])
print(xmin, ymin, xmax, ymax)
cv2.imwrite(filename, image)
I can't see what's wrong off hand, but it seems like something with the coordinates systems since the lower-right corner of the box is out of frame, or maybe the resizing. I'd start by looking at these values - can you print these out:
CAMERA_WIDTH, CAMERA_HEIGHT
input_height, input_width
ymin, xmin, ymax, xmax
start_point #(xmin,ymin)
end_point #(xmax,ymax)
And then display the model input image:
image = Image.open(stream).convert('RGB').resize(
(input_width, input_height), Image.ANTIALIAS)
And then display the image you are using to draw the bounding box:
open_cv_image

Place and insert plane image along path using matplotlib

My code is a fair bit more advanced, but in simple terms I am looking to place and rotate an image of a plane along a path using matplotlib. Ideally I would be able to select the angle and how far along the path the image should be placed. Any ideas? My ideal output would be something like this (ignoring the coordinates I already fixed that in my real code).
Image of Norway used:
Code
import matplotlib.pyplot as plt
import matplotlib.image as img
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def x2map(x, x_scale):
return x * x_scale
def y2map(y, y_scale):
return (1 - y) * y_scale
if __name__ == "__main__":
image_url = "Norge2.png"
# Obtains the scaling for the figure
map = img.imread(image_url)
fig, ax = plt.subplots()
im = ax.imshow(map)
_, x_scale = plt.xlim()
y_scale, _ = plt.ylim()
# Fixes the axis to 0-1 and 0-1
positions_x = [i * x_scale / 10 for i in range(0, 11)]
positions_y = [i * y_scale / 10 for i in range(0, 11)]
labels = [i / 10 for i in range(0, 11)]
ax.set_xticks(positions_x)
ax.set_xticklabels([i / 10 for i in range(0, 11)])
ax.set_yticks(positions_y)
ax.set_yticklabels([(10 - i) / 10 for i in range(0, 11)])
route_color = "red"
route_ls = "-"
city_marker ="o"
city_color = "red"
A = [x2map(0.125,x_scale), y2map(0.14,y_scale)]
B = [x2map(0.772,x_scale), y2map(0.92,y_scale)]
plt.plot(
[A[0], B[0]], [A[1], B[1]], marker='o', color=route_color, ls=route_ls
)
plt.show()

Creating a gui instead figure

First time posting here.
I need to create GUI that will upload video from my webcam and zoom in specific part of the video.
My code works for zooming but instead a Gui, it creates a figure.
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import tkinter as tk
from tkinter import *
from tkinter import ttk
import cv2
boxSize = 150
enlargeBy = 3
def getBoxCoordinates(cap, size):
width = cap.get(3)
height = cap.get(4)
x1 = int(width / 2) - int(size / 2)
y1 = int(height / 2) - int(size / 2)
x2 = int(width / 2) + int(size / 2)
y2 = int(height / 2) + int(size / 2)
return [(x1, y1), (x2, y2)]
def getBox(cap, boxSize, frame, enlargeBy):
[(x1, y1), (x2, y2)] = getBoxCoordinates(cap, boxSize);
# Get pixels in box
box_img = frame[y1 + 1:y2, x1 + 1:x2] # +1 cuz it excludes initial
pixel interval
return cv2.resize(box_img, None, fx=enlargeBy, fy=enlargeBy,
interpolation=cv2.INTER_LINEAR) # different
interpolation methods
cap = cv2.VideoCapture(0);
ret, frame = cap.read()
figWidth = 20
figHeight = 8
fig = plt.Figure(figsize=(figWidth, figHeight))
enlarged = getBox(cap, boxSize, frame, enlargeBy)
[(x1, y1), (x2, y2)] = getBoxCoordinates(cap, boxSize);
#cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255), lineType=1)
video_plot = plt.subplot2grid((figHeight, figWidth), (0, 0), colspan=4,
rowspan=4)
video_plot.axis('off')
video_plot.set_title("Camera feed")
video = video_plot.imshow(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
rectangle = plt.Rectangle((x1,y1), x2-x1, y2-y1, edgecolor="gold",
fill=False)
video_plot.add_patch(rectangle)
def updatefig(i):
ret, frame = cap.read()
video.set_data(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
return [video]
ani = animation.FuncAnimation(fig, updatefig, interval=20, frames=200,
blit=True)
plt.tight_layout()
plt.show()
cv2.destroyAllWindows()
plt.show()

Having Runtime Error while making a Radar Chart with matplotlib

I am trying to make an radar chart to look at the characteristics of the clusters formed by KMeans. The chart was plotting, but when I changed the variables I want to plot, it throws a run time error with incomplete radarchart. I am using the following code:
def _scale_data(data, ranges):
(x1, x2) = ranges[0]
d = data[0]
return [(d - y1) / (y2 - y1) * (x2 - x1) + x1 for d, (y1, y2) in zip(data, ranges)]
class RadarChart():
def __init__(self, fig, location, sizes, variables, ranges, n_ordinate_levels = 6):
angles = np.arange(0, 360, 360./len(variables))
ix, iy = location[:] ; size_x, size_y = sizes[:]
axes = [fig.add_axes([ix, iy, size_x, size_y], polar = True,
label = "axes{}".format(i)) for i in range(len(variables))]
_, text = axes[0].set_thetagrids(angles, labels = variables)
for txt, angle in zip(text, angles):
if angle > -1 and angle < 181:
txt.set_rotation(angle - 90)
else:
txt.set_rotation(angle - 270)
for ax in axes[1:]:
ax.patch.set_visible(False)
ax.xaxis.set_visible(False)
ax.grid("off")
for i, ax in enumerate(axes):
grid = np.linspace(*ranges[i],num = n_ordinate_levels)
grid_label = [""]+["{:.0f}".format(x) for x in grid[1:-1]]
ax.set_rgrids(grid, labels = grid_label, angle = angles[i])
ax.set_ylim(*ranges[i])
self.angle = np.deg2rad(np.r_[angles, angles[0]])
self.ranges = ranges
self.ax = axes[0]
def plot(self, data, *args, **kw):
sdata = _scale_data(data, self.ranges)
self.ax.plot(self.angle, np.r_[sdata, sdata[0]], *args, **kw)
def fill(self, data, *args, **kw):
sdata = _scale_data(data, self.ranges)
self.ax.fill(self.angle, np.r_[sdata, sdata[0]], *args, **kw)
def legend(self, *args, **kw):
self.ax.legend(*args, **kw)
def title(self, title, *args, **kw):
self.ax.text(0.9, 1, title, transform = self.ax.transAxes, *args, **kw)
#Plotting
fig = plt.figure(figsize=(14,16))
attributes = ['total_disabled', 'average_payment_amount', 'avg_days_btwn_payments', 'days_since_1st_transaction','days_since_last_transaction','amount_pending']
ranges = [[0.01, 1000], [0.01, 10000], [0.01, 50], [0.01, 1000], [0.01, 500], [0.01, 10000]]
index = [0, 1, 2, 3, 4, 5,6,7]
n_groups = n_clusters ; i_cols = 3
i_rows = n_groups//i_cols
size_x, size_y = (1/i_cols), (1/i_rows)
for ind in range(n_clusters):
ix = ind%3 ; iy = i_rows - ind//3
pos_x = ix*(size_x + 0.05) ; pos_y = iy*(size_y + 0.05)
location = [pos_x, pos_y] ; sizes = [size_x, size_y]
#______________________________________________________
data = np.array(clustered_df.loc[index[ind], attributes])
radar = RadarChart(fig, location, sizes, attributes, ranges)
radar.plot(data, color = 'b', linewidth=2.0)
radar.fill(data, alpha = 0.2, color = 'b')
radar.title(title = 'cluster nÂș{}'.format(index[ind]), color = 'r')
ind += 1
And it gives the following error:
C:\Users\arindam\Anaconda3\lib\site-packages\pandas\core\indexing.py:1020: FutureWarning:
Passing list-likes to .loc or [] with any missing label will raise
KeyError in the future, you can use .reindex() as an alternative.
See the documentation here:
http://pandas.pydata.org/pandas-docs/stable/indexing.html#deprecate-loc-reindex-listlike
C:\Users\arindam\Anaconda3\lib\site-packages\matplotlib\projections\polar.py:65: RuntimeWarning:
invalid value encountered in less
I hope someone can help me out with this. Thanks in advance.

Tkinter create shrinking circle on each mouse click, how to make it work with multiple clicks?

I am creating a simple program which draws a shrinking circle of random color on every clicked location by each mouse click. Each click creates a circle of diameter 50 which starts shrinking till 0 immediately. Each click is supposed to create new shrinking circle.
However, my program stops shrinking of first circle after I click and create another circle. It completely shrinks only the last created circle. All others remain still.
I believe the problem lies in function itself. It calls the same function which is not finished. How to make it run multiple times (on each click separately)? Or do I have it wrong with local and global variables?
Here is my code so far:
import tkinter
import random
c = tkinter.Canvas(width = 400, height = 300)
c.pack()
def klik(event):
global x, y, farba, circ, r
r = 50 #circle diameter
x, y = event.x, event.y #clicked position
color = '#{:06x}'.format(random.randrange(256 ** 3)) #random color picker
circ = c.create_oval(x - r, y - r, x + r, y + r, fill=color) #print circle
print(x, y, farba) #check clicked coordinates, not important
if r < 50: #reset size after each circle
r = 50
shrink()
def shrink():
global circ, x, y, r
print(r) #check if countdown runs correctly
if r > 0:
r -= 1 #diameter shrinking
c.coords(circ, x-r, y-r, x+r, y+r) #changing circle size
c.after(100, shrink) #timer, size 1pt smaller until size is 0
c.bind('<Button-1>', klik)
tkinter.mainloop()
If you move everything into a class then each circle will be its own instance and will not interfere with each other.
Take a look at the below modified version of your code. It is probably not perfect but should be a good foundation for you to work with.
import tkinter
import random
c = tkinter.Canvas(width = 400, height = 300)
c.pack()
class create_circles():
def __init__(self, event):
self.r = 50
self.x, self.y = event.x, event.y
self.color = '#{:06x}'.format(random.randrange(256 ** 3))
self.circ = c.create_oval(self.x - self.r, self.y - self.r, self.x + self.r, self.y + self.r, fill=self.color)
self.shrink()
def shrink(self):
if self.r > 0:
self.r -= 1
c.coords(self.circ, self.x-self.r, self.y-self.r, self.x+self.r, self.y+self.r)
c.after(100, self.shrink)
c.bind('<Button-1>', create_circles)
tkinter.mainloop()
There is another way you can do this outside of a class.
You can use a nested function and avoid global. Your issues in your question is actually being caused because everything relies on global variables.
Try this below code for a non-class option.
import tkinter
import random
c = tkinter.Canvas(width = 400, height = 300)
c.pack()
def klik(event):
r = 50
x, y = event.x, event.y
color = '#{:06x}'.format(random.randrange(256 ** 3))
circ = c.create_oval(x - r, y - r, x + r, y + r, fill=color)
def shrink(r, x, y, color, circ):
if r > 0:
r -= 1
c.coords(circ, x-r, y-r, x+r, y+r)
c.after(100, shrink, r, x, y, color, circ)
shrink(r, x, y, color, circ)
c.bind('<Button-1>', klik)
tkinter.mainloop()
As noted, you do not need classes to solve this nor nested functions. The key, as #LioraHaydont was hinting at, is you need to use local, rather than global variables:
import tkinter as tk
from random import randrange
def klik(event):
r = 50 # circle radius
x, y = event.x, event.y # clicked position
color = '#{:06x}'.format(randrange(256 ** 3)) # random color picker
c = canvas.create_oval(x - r, y - r, x + r, y + r, fill=color) # print circle
canvas.after(100, shrink, c, x, y, r)
def shrink(c, x, y, r):
if r > 0:
r -= 1 # radius shrinking
canvas.coords(c, x - r, y - r, x + r, y + r) # changing circle size
canvas.after(100, shrink, c, x, y, r) # timer, size 1pt smaller until size is 0
canvas = tk.Canvas(width=400, height=300)
canvas.pack()
canvas.bind('<Button-1>', klik)
tk.mainloop()

Resources