2

See main point below code chunk for quick summary

For research, I'm trying to write a photometry program in python (I know there is software out there, but there's a specific reason I'm writing my own). I am using Anaconda with Python 3.6 and can get the FITS file image to render, but I want to be able to click on a point and perform photometry.

Basically I want to bind the image to a tkinter canvas and have a click event to return the location.

I've been looking at almost the exact same question here, but the key differences are that I'm using a FITS file and python 3.6 (which changes a lot of the features in that example)

My code thus far (using much of what that example showed) is:

import numpy as np
import matplotlib.pyplot as plt
from astropy.io import fits
import scipy as sp
import tkinter as tk
import PIL

hdulist = fits.open('00000039.sat_26624U.fit')
hdulist.info()
scidata = hdulist[0].data

histo = sp.histogram(scidata, 60, None, True) 
display_min = histo[1][0]
display_max = histo[1][1]
pic = plt.imshow(scidata, cmap=plt.cm.gray, vmin=display_min, vmax=display_max, origin="lower")

#Try tk stuff
root = tk.Tk()

#setting up a tkinter canvas
frame = tk.Frame(root, bd=2, relief=tk.SUNKEN)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
canvas = tk.Canvas(frame, bd=0)
canvas.grid(row=0, column=0, sticky=tk.N+tk.S+tk.E+tk.W)
frame.pack(fill=tk.BOTH,expand=1)

#Add image
hold = tk.PhotoImage(pic)
canvas.create_image(0,0,image=hold,anchor="nw")

#function to be called when mouse is clicked
def printcoords(event):
    #outputting x and y coords to console
    print (event.x,event.y)
#mouseclick event
canvas.bind("<Button 1>",printcoords)

root.mainloop()

hdulist.close()

Which shows the image but gives me an error at:

#Add image
hold = tk.PhotoImage(pic)
canvas.create_image(0,0,image=hold,anchor="nw")

That says:

TypeError: __str__ returned non-string (type AxesImage)

Main Point:
I can't get a FITS image to bind to a tkinter canvas. I don't know how to click that image and get the location of the mouse click. I want to be able to click a few points, get their locations, and use those locations to draw a few annuli.

I have plenty of other issues, but that's my main hang up right now. Eventually I will be trying to track them (move to the next picture and search roughly the same area until I find the object again, placing the annulus) and counting the pixels inside, but I can cross that bridge later (unless anyone has ideas now).

2 Answers2

1

After talking to some people, I found the issue to be that a tkinter canvas needs a file type like .gif or .png to bind an image to the canvas. So I changed

pic = plt.imshow(scidata, cmap=plt.cm.gray, vmin=display_min, vmax=display_max, origin="lower")

to

plt.imsave("tempimgfile.gif", scidata, cmap=plt.cm.gray, vmin=display_min, vmax=display_max, origin="lower")

and

hold = tk.PhotoImage(pic)

to

hold = tk.PhotoImage(file="tempimgfile.gif")

saving my numpy array as a gif file just long enough to bind, then deleting it after.

Bottom line: Convert a FITS file to .gif or other compatible type

It may not be the most elegant fix, but it worked

0

You have to do some changes in the code. First of all I would prefer to use the Place() method in Tkinter . You can look at place Method here how to i position buttons in tkinter?

Second thing : By using the place method it will be suitable for your application.

Hint: Place() Method works with x and y co-ordinates. So the two elements can overlap in Tkinter using Place() but it is not possible in Grid.

Now with Place() method place the image in some area in Tkinter window let say the image size is 100x100 and then make a button with the function call and place it behind the image giving the same co-ordinates in Place() Method. So when a user will click on image it will actually calls the function behind the button.

babygame0ver
  • 447
  • 4
  • 16