This package can be used on Windows, Linux, and MacOS operating systems.

Windows users may download the git repository or do a direct pip install from the git repository. However, they will not have default access to DS9 because compiling the cython+xpa code cannot currently be done with default installed software. Instead, Windows users should make sure they install the Ginga viewer for image examination and plotting using it’s HTML5 viewer. You will have all the same imexam functionality available to you, including the use of Jupyter notebooks and screen plotting.

imexam currently provides display support two viewers: DS9 and Ginga. The default, when no parameters are supplied to the connect call, is for imexam to start up it’s own DS9 process and shut it down nicely upon exit. A Ginga widget using an HTML5 backend is also available as a viewer, most usefull when interacting with the package inside a Jupyter notebook. The package is designed so that it may easily accept other display devices in the future. Additionally, an experimental ginga plugin is available which allows use of the basic ginga gui and interaction with the image display and plots in the imexam style.

The imexam library can be used standalone, without a viewer, to create the plots which are available in the interactive sessions by importing the plotting object and feeding the functions your data with x,y coordinates for the plots. It can also be used within the Jupyter notebook framework with either DS9 or the HTML5 backend for viewing. In either case, the images and plots may be saved inside the notebook in conjunction with the notebook (nbAgg) matplotlib backend. If you choose to interact with separate plotting windows, it’s still possible to grab an image of the current image display or plot and save it inside the notebook.


For DS9, it is important to know if you have XPANS installed on your machine and available through your PATH if you plan to use the nameserver functionality. XPANS is the XPA Name Server, it keeps track of all the open socket connections for DS9 and provides a reference for their names. If you DO NOT have XPANS installed, then imexam will still work, but you should either start the DS9 window after importing imexam through the imexam.connect() interface, OR after you start DS9 from the shell.

You can connect to an already open DS9 window by specifying the title or the XPA_METHOD. The XPA_METHOD is the address in the File->Information dialog. If users don’t specify a title in the ds9 window when they open one up, ds9 will just call the window “ds9”, so you can end up with multiple windows with the same name. This works for DS9 because the XPA_METHOD is always unique. The most straightforward way is for users to open the DS9 windows with explicit titles, and then tell imexam to connect to that window:

python> !ds9 -title megan
python> window=imexam.connect('megan')

However, if there are windows already open with no unique titles, the best way is to connect using the method. The list_active_ds9 function can be used to return a dictionary which contains the information for all the windows, but it’s keys are the unique XPA_METHOD strings.:

In [3]: !ds9&
In [4]: imexam.list_active_ds9()
DS9 ds9 gs c0a80106:61894 sosey
Out[4]: {'c0a80106:61894': ('ds9', 'sosey', 'DS9', 'gs')}

Using this dictionary, you can also you can return the list of windows you can connect to without too much thinking, making it easy to encorporate into your own scripts as well::

In [1]: import imexam

In [2]: windows=imexam.list_active_ds9()
DS9 ds9 gs c0a80106:61915 sosey

In [3]: list(windows)
Out[3]: ['c0a80106:61915']

In [4]: !ds9&

In [5]: windows=imexam.list_active_ds9()
DS9 ds9 gs c0a80106:61915 sosey
DS9 ds9 gs c0a80106:61923 sosey

In [6]: list(windows)
Out[6]: ['c0a80106:61915', 'c0a80106:61923']

In [7]: ds9=imexam.connect(list(windows)[0])

But you can also use it as below to cycle through connecting to a set of windows::

In [8]: windows=imexam.list_active_ds9()
DS9 ds9 gs c0a80106:61915 sosey
DS9 ds9 gs c0a80106:61923 sosey

In [9]: ds=imexam.connect(windows.popitem()[0]) #connect to first window, remove as possible window
In [10]: windows
Out[11]: {'c0a80106:61923': ('ds9', 'sosey', 'DS9', 'gs')}

In [12]: w2=imexam.connect(windows.popitem()[0])

In [13]: windows
Out[31]: {}

In order to use the Ginga widget display you must have Ginga installed. More information about Ginga can be found in its package documentation: If you are using Python 3 you should also install Pillow which will aid in the image display. The Ginga documentation will tell you of any of it’s other dependencies. If you install Ginga you will have access to another display tool for your images and data, the HTML5 widget. You can find the source code on GitHub, but you can also install it with pip or conda.

You can access this help file on your locally installed copy of the package by using the imexam.display_help() call after import. This will display the help in your web browser.


All information returned from this module should be considered an estimate of an actual refined result, more precise analysis of the data should be performed for verification before publication.

How to Install

These are some tips on installing the package, or tracking down problems you might be having during or after installation.

imexam can be installed from the source code in the normal python fashion after downloading it from the git repo:

python install

imexam can also be installed using pip or conda, and is included in the Astroconda distribution from STScI:

# from PyPI
pip install imexam

# if you already have an older version installed
pip install --upgrade imexam

# from the master trunk on the repository, considered developmental code
pip install git+

#install version 0.6.3 from the git repository, this uses the git tag reference
pip install git+

# from the STScI conda release package
conda install imexam -c

If you want to have access to the photometry features of the imexam() analysis, download and install photutils - another of the astropy associated packages. The full list of astropy packages can be found here: If photutils is not installed, imexam should issue a nice statement saying that the photometry options are not available upon import, and any time an analysis key is pressed during the imexam() function loop which requires photutils to render a result.


imexam displays plots using matplotlib, if you find that no windows are popping up after installation it’s probably the backend that was loaded. One quick way to get things started is to load ipython and use the %matplotlib magic, this will make sure the proper display backend loads when matplotlib is imported:

>import imexam

Matplotlib magic should also be used inside the Jupyter notebook or proper interaction with the plots. Before importing imexam into the notebook, specify the notebook backend if you wish to save your plots into the notebook itself. Otherwise you can use the standard ipython magics.

imexam is a class based library. The user creates an object which is tied to a specific image viewing window, such as a DS9 window. In order to interact with multiple windows the user must create multiple objects. Each object stores all the relevent information about the window and data with which it is associated.

For example, in order to open a new DS9 window and use the object “viewer” to control it, you would issue the command:


The “viewer” object now has associated methods to view, manipulate and analyze data in the DS9 session. When you start the connection, you also have the option of specifying a currently open DS9 window using the target keyword. This keyword can contain the name, the actual text name that you gave the window, or the address of the window. The address of the window can be found in the File->XPA->Information menu item, is stored as XPA_METHOD, and is of the form “82a7e75f:58576” for INET sockets, and a file path for local sockets. The following is an example of connecting to an already active DS9 window which was started outside of imexam:




When imexam starts up a DS9 window itself, it will create an inet socket by default. However, imexam will first check to see if XPA_METHOD was set in your environment and default to that option. If you are experiencing problems, or you don’t have an internet connection (the two might be related because the XPA structures INET sockets with an ip address), you can set your environment variable XPA_METHOD to local or localhost. This will cause imexam to start a local(unix) socket which will show an XPA_METHOD that is a filename on your computer. imexam defaults to a local socket connection to allow for users who do not have the XPA installed on their machine or available on their PATH.

The full XPA source code is maintained as a submodule to the imexam package. If you don’t have the XPA on your path, simply point it to that location, or copy the xpans executable to the location of your choice, and make sure you update your PATH. Any time DS9 is started it will start up the xpa nameserver automatically. Then all the xpans query options will be available through imexam (such as imexam.list_active_ds9()). imexam itself uses Cython wrappers around the get and set methods from the XPA for it’s communication which is why the fully installed XPA is not necessary.

If you wish to open multiple DS9 windows outside of imexam, then it’s recommended that you give each a unique name. If you’ve forgotten which window had which name, you can look in the same XPA info menu and use the XPA_NAME specified there. If you haven’t given them a unique name, you can list the available windows using imexam.list_active_ds9() (as long as XPANS is running) and specify their unique address.

imexam will attempt to find the current location of the DS9 executable by default, but you may also supply the path to the DS9 executable of your choice using the path keyword when you call connect. The fully optional calling sequence is:


Where target is the name of the ds9 window that is already running, path is the location of the ds9 executable, viewer is the name of the viewer to use (ds9 is the only one which is currently activated), and wait_time is the time to wait to establish a connection to the socket before exiting the process.

If it seems like the ds9 window is opening or hanging, there could be few things going on:

  • imexam will default to an inet socket connection for the XPA. However, it will first check your environment variable XPA_METHOD and preferably use that instead. If you don’t have an internet connection, check this environment variable, and set it to “local”.
  • If things seem in order, it’s possible that your machine is waiting for X11 to start up, give it time to start, or when you call imexam increase the wait time sufficiently; you can do this by specifying “wait_time=60” when you open your viewing object with connect(). The 60 here is an example of the number of seconds imexam should wait before returning a connection error.
  • Next, check that the path to the DS9 executable is somewhere on your path and that it has not been aliased to something else. You can check this from any terminal window by trying to start DS9. You can also use the unix “which ds9” command to return the full path to the executable, as well as “ls -al ds9” to return the full path and any soft links which might have been established.

In order to return a list of the current DS9 windows that are running, issue the command:



More information on DS9 can be found at:

If you are using the Ginga widget, the interaction with the imexam code stays the same, you simply specify that you would like to use Ginga in the call to connect:


“ginga” tells imexam that you’d like to use the Ginga widget with the HTML5 background.

In order to turn logging to a file on, issue the command: window.setlog(). The log will be saved to the default filename imexam_session.log in the current directory unless you give it another filename to use. Here’s an example of how that might work:

import imexam
window.setlog() <-- turns on logging with default filename
window.imexam() <-- all output will be logged to the file and displayed on the screen
window.setlog(on=False) <-- turns off logging to file
window.setlog(filename='my_other_log.txt') <-- turns on logging and sets the save filename

The log will look something like this, you can see it contains a mention of the command used along with the results

xc=812.984250   yc=706.562612

x       y       radius  flux    mag(zpt=25.00)  sky     fwhm
812.98  706.56  5       1288669.29      9.72    11414.53        4.83

813.5 706.625

xc=812.984250   yc=706.562612

xc=239.856464   yc=233.444783

x       y       radius  flux    mag(zpt=25.00)  sky     fwhm
239.86  233.44  5       126601.26       12.24   11574.32        -12.67

253.0 234.75

xc=239.856464   yc=233.444783

More detailed examples can be found in the examples section of this documentation.

Common Problems

You’re getting the following error statement when you try to connect() to a DS9 window, or display an image:

XpaException: Unknown XPA Error : XPAGet returned 0!

You can first try using local unix sockets by setting your environment variable XPA_METHOD to local:

setenv XPA_METHOD local    #csh

or if you have a bash-like shell:

export XPA_METHOD="local"

or if you want to do it from inside Python:

import os
os.environ['XPA_METHOD'] = "local"

That will create local unix file sockets for communication with ds9. If that doesn’t solve the problem, see if your path includes the location of xpans, the XPA name server. If you have it installed, but it’s not on your path, put it there.

Alternatively, if you’re getting an error on calling connect() along the lines of:

Connection timeout with the ds9

you may want to force XPA to use the “inet” mode, which is the default unless your XPA_METHOD is set. E.g.,

setenv XPA_METHOD inet   #csh
export XPA_METHOD='inet' #bash

(Or similar based on the examples above)

If you are having display issues, some build problems may exist with the dependency packages which deal with backend graphics, try setting your matplotlib backend to “Qt4Agg”. You can set this in your .matplotlib/matplotlibrc file

backend: Qt4Agg

The package works with the Qt5Agg and notebook backends, but on occasion I’ve seen the matplotlib window take two cycles to update, especially inside the Jupyter notebook with inline plots, meaning you may have to hit the exam key twice for the plot to appear. This issue still needs to be worked out, if you’re running into it try using the Qt4Agg backend or plotting outside the notebook and saving the figures through the imexam grab or save calls. More information about the backends for matplotlib can be found here:

If you get an error about not finding the file “import” when you use the grab() function to save a copy of the DS9 window.

`FileNotFoundError: [Errno 2] No such file or directory: 'import' `

“import” is the unix/linux import command, it saves any visible window on an X server and outputs it as an image file, it’s included with many macos and linux installations, it’s likely not on windows. Users should check their path to see if it’s included. This only affects grab() for DS9 which saves a copy of the DS9 window on the workspace, it does not affect saves for ginga or matplotlib plots.

imexam switched to using import to get around a bug in the XPA for the saveimage call to the XPA. The DS9 saveimage function basically does a screen capture. In the case of MacOSX (and XQuartz) when you are configured to be rootless, the screen capture fails if your DS9 window is not in the upper left corner of the primary screen - the call should work if you are using a laptop that is not connected to a larger display, or a workstation with only one monitor. Since these are harder things to automatically grab from user environments, the workaround was to ‘Print’ to a file, generating a postscript image that can be rendered outside of ds9 (for example /Applications/Preview). However, I was unable to get this to save to file, the functions it insisted on sending the image directly to the printer. This also makes for greater unknowns on user machines. The workarounds for users who hit this may be:

  • screen grab a copy of the window yourself (grabbing saves any overlays as well)
  • move the DS9 window to the appropriate screen and issue the saveimage command, assuming “a” is your control object, that would look like: a.window.xpa.set(“saveimage ds9.jpeg”)

If you are experiencing an issue not related to those descibed above you can open a new issue on the imexam GitHub issue tracker. You can view older closed issues there as well.