Git Product home page Git Product logo

imexam's Introduction

imexam

CI Status Documentation Status Test Coverage Status Powered by Astropy Zenodo

imexam is an affiliated package of AstroPy. It was designed to be a lightweight library which enables users to explore data from a command line interface, through a Jupyter notebook or through a Jupyter console. It can be used with multiple viewers, such as DS9 or Ginga, or without a viewer as a simple library to make plots and grab quick photometry information. It has been designed so that other viewers may be easily attached in the future.

For more information please see the online documentation

Note: There is one git submodule in this package, a submodule for the xpa code that talks to DS9. If you are planning to work on developing new code or installing this package from a repo download, you need to pull the xpa code using the following command after you have cloned the repository and before you "python setup.py install"

git submodule update --init -- cextern/xpa

If you are cloning the repository for the first time, you can do both steps at once using a recursive clone:

git clone --recursive https://github.com/spacetelescope/imexam.git

You can also display the docs locally after install, import imexam and then issue the following command to display the help docs in your local browser:

imexam.display_help()

To install using pip:

pip install imexam   #installs from the most recent pypi binaries

pip install git+https://github.com/spacetelescope/imexam  #installs from the current master on this repo

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

If you receive a message like this on your Mac OSX Lion+ machine when imexam.imexam() runs:

2016-02-01 11:16:11.453 python[84657:2506524] ApplePersistenceIgnoreState: Existing state will not be touched.

Try turning off the resume state:

defaults write org.python.python ApplePersistenceIgnoreState NO

Contributing

Please open a new issue or new pull request for bugs, feedback, or new features you would like to see. If there is an issue you would like to work on, please leave a comment and we will be happy to assist. New contributions and contributors are very welcome!

New to GitHub or open source projects? If you are unsure about where to start or haven't used github before, please feel free to contact @sosey. Want more information about how to make a contribution? Take a look at the astropy contributing and developer documentation.

Feedback and feature requests? Is there something missing you would like to see? Please open an issue or send an email to @sosey. imexam follows the Astropy Code of Conduct and strives to provide a welcoming community to all of our users and contributors.

License

imexam is licensed under a 3-clause BSD style license (see the licenses/LICENSE.rst file).

Quick Instructions

If you are having display issues, and you are using TkAgg, try setting your matplotlib backend to Qt4Agg or Qt5Agg. You can set this in your .matplotlib/matplotlibrc file. You may also want to switch your matplotlib backend to Qt if you have a mac with the default MacOS backend specified. If you don't already have matplotlibrc file in your home directory, you can download one from their documentation: https://matplotlib.org/_static/matplotlibrc

inside ~/.matplotlib/matplotlibrc:
backend: Qt4Agg

Using the Ginga HTML5 Viewer

If you have installed Ginga, you can use the HTML5 viewer for image display with either a jupyter console, qtconsole or Jupyter notebook session. If you are using a Windows machine you should install ginga to use as the viewer with this package. Make sure that you have installed the latest version, or you can download the development code here: https://github.com/ejeschke/ginga.

There is also a ginga plugin for imexam which is in the ginga repository in the experimental directory. This will load the imexam plotting and analysis library into the ginga gui framework.

Starting a connection to a Ginga HTML5 canvas backend for browser and Jupyter viewing:

a = imexam.connect(viewer='ginga')

You can optionally provide a port number to which the viewer is connected as well:

a=imexam.connect(viewer='ginga', port=9856)

Using imexam with DS9

From a python terminal: using either the TkAGG or QT4Agg/QT5Agg backends:

import imexam
a = imexam.connect()
a.imexam()

From an ipython terminal: using either the TkAgg or QT4Agg/QT5Agg backends.

import imexam
a = imexam.connect()

If you are using TkAGG as the backend, from an ipython terminal, you may need to ctrl-D, then select n, to closeout the plotting window. This should not happen if you are running TkAgg and running from a regular python terminal. Looking into the closeout issue with TkAgg now.

From jupyter console/qtconsole: startup with the matplotlib magics to use the backend you specified for display:

In [1]: %matplotlib
import imexam
a = imexam.connect()

If you are using the Qt4Agg/Qt5Agg backend with ginga, the plots will display in the console window

Launching multiple DS9 windows

You can launch multiple ds9 windows either from this package or the command line. DS9 can be used to view images and arrays from any of the python terminals, consoles or the Jupyter notebook.

If you launch ds9 from outside the imexam package, you need supply the name of the window to imexam, this can be done in one of 2 ways:

  • launch ds9 with a unique title name:
ds9 -title astronomy&

then supply imexam the name of the window:

a=imexam.ds9('astronomy')
  • launch ds9 with nothing:
ds9&

then supply imexam with the XPA_METHOD from the XPA information window, this variable will contain either the INET address or the local filename representing the socket:

a=imexam.connect('82a7e674:51763')

Starting a new connection with no target specified will open a new DS9 window using a local socket by default:

a=imexam.connect()

Connecting to a DS9 window which was started from the system prompt:

imexam.list_active_ds9() # will give you the INET address or names of the open session
a=imexam.connect('address from the above listing')

Examples can be found in the package documentation, online documentation, and imexam.display_help() will pull up the installed package documentation in a web browser. You can also download the example Jupyter notebooks available in the example_notebooks directory above.

You can also just load the plotting library for use without a viewer:

This is useful when you want to make batch plots or return information . from scripts You can also save the lotting data returned and use it . further, or design your own plot .

from imexam.imexamine import Imexamine
import numpy as np

plots = Imexamine()  #the plots object now has all available functions
data = np.random.rand(100,100) * np.ones((100,100)) #make some fake data
plots.plot_line(35,45,data) #shows a matplotlib window with a plot
plots.save() #saves the current plot to file

You can also set the data attribute of the plots object and then just call many plots without specifying the data again:

plots.set_data(data)
plots.plot_line(35,45)

imexam's People

Contributors

astrofrog avatar bsipocz avatar cdeil avatar ejeschke avatar embray avatar eteq avatar heatherkurtz avatar jsoref avatar larrybradley avatar mwcraig avatar pllim avatar sosey avatar stscieisenhamer avatar tjhoyt avatar yoachim avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

imexam's Issues

get_viewer_info()

get_viewer_info() checks the current frame information and returns the calling objects dictionary of information for all the frames it knows about in the viewer. If a user loads images through the GUI exclusively, they wont get added to the dictionary automatically, they will get added when a user calls a function which references the frame.

This presents as a problem when the user opens a ds9 window, then uses the gui to load an image and the very next command is viewer.imexam(), nothing happens the first time because the dictionary isn't populated, the second time it's called will succeed. This was traced back to the valid_data_in_viewer() which should be updated so that the logic structure populates the dictionary if something is loaded and not registered. The dictionary also needs to be updated if the user deleted the frame through the gui

Automated build of OSX wheels

I have set up a repository to do automated builds of OSX wheels:

https://github.com/MacPython/imexam-wheels

The last build using current master succeeded:

https://travis-ci.org/MacPython/imexam-wheels

The travis run uploads the built wheel to the scikit-learn Rackspace container:

http://wheels.scipy.org

Here is me installing imexam into an OSX virtualenv:

$ pip install -f http://wheels.scipy.org imexam==0.5
You are using pip version 6.1.1, however version 7.1.0 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Collecting imexam==0.5
  This repository located at wheels.scipy.org is not a trusted host, if this repository is available via HTTPS it is recommend to use HTTPS instead, otherwise you may silence this warning with '--trusted-host wheels.scipy.org'.
  DEPRECATION: Implicitly allowing locations which are not hosted at a secure origin is deprecated and will require the use of --trusted-host in the future.
  Downloading http://wheels.scipy.org/imexam-0.5-cp27-none-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl (7.1MB)
    100% |████████████████████████████████| 7.1MB 3.4MB/s 
Collecting Cython (from imexam==0.5)
  This repository located at wheels.scipy.org is not a trusted host, if this repository is available via HTTPS it is recommend to use HTTPS instead, otherwise you may silence this warning with '--trusted-host wheels.scipy.org'.
  Using cached Cython-0.22.1-cp27-none-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl
Collecting numpy>=1.6.0 (from imexam==0.5)
  This repository located at wheels.scipy.org is not a trusted host, if this repository is available via HTTPS it is recommend to use HTTPS instead, otherwise you may silence this warning with '--trusted-host wheels.scipy.org'.
  Using cached numpy-1.9.2-cp27-none-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl
Collecting scipy (from imexam==0.5)
  This repository located at wheels.scipy.org is not a trusted host, if this repository is available via HTTPS it is recommend to use HTTPS instead, otherwise you may silence this warning with '--trusted-host wheels.scipy.org'.
  Using cached scipy-0.16.0-cp27-none-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl
Collecting astropy-helpers (from imexam==0.5)
  This repository located at wheels.scipy.org is not a trusted host, if this repository is available via HTTPS it is recommend to use HTTPS instead, otherwise you may silence this warning with '--trusted-host wheels.scipy.org'.
  Using cached astropy-helpers-1.0.3.tar.gz
Collecting astropy>=1.0 (from imexam==0.5)
  This repository located at wheels.scipy.org is not a trusted host, if this repository is available via HTTPS it is recommend to use HTTPS instead, otherwise you may silence this warning with '--trusted-host wheels.scipy.org'.
  Using cached astropy-1.0.3-cp27-none-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl
Installing collected packages: Cython, numpy, scipy, astropy-helpers, astropy, imexam
  Running setup.py install for astropy-helpers
Successfully installed Cython-0.22.1 astropy-1.0.3 astropy-helpers-1.0.3 imexam-0.5 numpy-1.9.2 scipy-0.16.0

The wheel gets the default version string for tag v0.5 in the repo - which gives version 0.5. It looks as if the code for tag v0.5 is identical to the pypi source code for version=0.5.2 bar some egg metadata, but I don't know how to set the version correctly to 0.5.2, because setup.py is using some astropy routines to get the version, as far as I can see.

I added @sosey to the owners for the wheel-building repo - should I add anyone else?

Radial plots showing all the pixels

The IRAF imexam radial plots show all the pixels, rather than binned by radius. This is useful for evaluating the quality of centroids or PSF fits. My suggestion is that this be the default for python imexam. Binned plots with uncertainties might be useful too, but I think are typical inspection.

Possible XPA communication problem on Mac OS 10.8.5

Connection timeout with the ds9. Try to increase the wait_time parameter (current value is 10 s)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/lubeda/astronomy/site-packages/lib/imexam-0.3.dev-py2.7-macosx-10.6-x86_64.egg/imexam/connect.py", line 62, in __init__
    target=target, path=path, wait_time=wait_time, quit_ds9_on_del=quit_window)
  File "/Users/lubeda/astronomy/site-packages/lib/imexam-0.3.dev-py2.7-macosx-10.6-x86_64.egg/imexam/ds9_viewer.py", line 213, in __init__
    self._set_frameinfo()  # initial load
  File "/Users/lubeda/astronomy/site-packages/lib/imexam-0.3.dev-py2.7-macosx-10.6-x86_64.egg/imexam/ds9_viewer.py", line 246, in _set_frameinfo
    frame = self.frame()
  File "/Users/lubeda/astronomy/site-packages/lib/imexam-0.3.dev-py2.7-macosx-10.6-x86_64.egg/imexam/ds9_viewer.py", line 886, in frame
    frame = self.get("frame").strip()  # xpa returns '\n' for no frame
  File "/Users/lubeda/astronomy/site-packages/lib/imexam-0.3.dev-py2.7-macosx-10.6-x86_64.egg/imexam/ds9_viewer.py", line 617, in get
    return self.xpa.get(param)
  File "/Users/lubeda/astronomy/site-packages/lib/imexam-0.3.dev-py2.7-macosx-10.6-x86_64.egg/imexam/xpa_wrap.py", line 12, in get
    r = xpa.get(self, param.encode("ascii"))
  File "xpa.pyx", line 172, in xpa.xpa.get (wrappers/xpa.c:1797)
  File "xpa.pyx", line 112, in xpa._get (wrappers/xpa.c:1037)
xpa.XpaException: XPA$ERROR: no response from server during handshake (?:?)

Improve user interface for changing plot defaults

Currently users have to access the default plotting parameters directly through the dictionary. It would be nice to change this structure so that it wasn't so cumbersome and a little more intuitive

Cannot install imexam from source

In trying to test Eric J's #78, I get the following traceback on RHEL6 64-bit:

Initializing astropy_helpers submodule with: `git submodule update --init -- astropy_helpers`
Freezing version number to imexam/version.py
Compiling wrappers/xpa.pyx because it changed.
[1/1] Cythonizing wrappers/xpa.pyx
.../python3.5/site-packages/setuptools-22.0.5-py3.5.egg/setuptools/dist.py:285: UserWarning: Normalizing '0.6.3dev260' to '0.6.3.dev260'
running install
running bdist_egg
running egg_info
creating imexam.egg-info
writing top-level names to imexam.egg-info/top_level.txt
...
copying imexam/tests/coveragerc -> build/lib.linux-x86_64-3.5/imexam/tests
running build_ext
make: Makefile: No such file or directory
make: *** No rule to make target `Makefile'.  Stop.
sh: ./configure: No such file or directory
make: Makefile: No such file or directory
make: *** No rule to make target `Makefile'.  Stop.
building 'xpa' extension
creating build/temp.linux-x86_64-3.5
creating build/temp.linux-x86_64-3.5/wrappers
creating build/temp.linux-x86_64-3.5/cextern
creating build/temp.linux-x86_64-3.5/cextern/xpa
gcc -pthread -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -DHAVE_CONFIG_H=1 -Icextern/xpa/ -I/.../include/python3.5m -c wrappers/xpa.c -o build/temp.linux-x86_64-3.5/wrappers/xpa.o
wrappers/xpa.c:285:17: error: xpa.h: No such file or directory
wrappers/xpa.c:517: error: expected specifier-qualifier-list before ‘XPARec’
wrappers/xpa.c:735: error: expected ‘)’ before ‘*’ token
wrappers/xpa.c:736: error: expected ‘)’ before ‘*’ token
wrappers/xpa.c: In function ‘__pyx_pf_3xpa_nslookup’:
wrappers/xpa.c:909: warning: implicit declaration of function ‘XPANSLookup’
wrappers/xpa.c: At top level:
wrappers/xpa.c:1087: error: expected declaration specifiers or ‘...’ before ‘XPARec’
wrappers/xpa.c: In function ‘__pyx_f_3xpa__get’:
wrappers/xpa.c:1112: warning: implicit declaration of function ‘XPAGet’
wrappers/xpa.c: In function ‘__pyx_pf_3xpa_2get’:
wrappers/xpa.c:1450: error: too many arguments to function ‘__pyx_f_3xpa__get’
wrappers/xpa.c: At top level:
wrappers/xpa.c:1483: error: expected ‘)’ before ‘*’ token
wrappers/xpa.c: In function ‘__pyx_pf_3xpa_4set’:
wrappers/xpa.c:1848: warning: implicit declaration of function ‘__pyx_f_3xpa__set’
wrappers/xpa.c:1848: warning: assignment makes pointer from integer without a cast
wrappers/xpa.c: In function ‘__pyx_f_3xpa_3xpa__set_template’:
wrappers/xpa.c:1904: error: ‘struct __pyx_obj_3xpa_xpa’ has no member named ‘_template’
wrappers/xpa.c:1914: error: ‘struct __pyx_obj_3xpa_xpa’ has no member named ‘_template’
wrappers/xpa.c: In function ‘__pyx_pf_3xpa_3xpa___init__’:
wrappers/xpa.c:2017: error: ‘struct __pyx_obj_3xpa_xpa’ has no member named ‘_xpa’
wrappers/xpa.c:2017: warning: implicit declaration of function ‘XPAOpen’
wrappers/xpa.c: In function ‘__pyx_pf_3xpa_3xpa_2__del__’:
wrappers/xpa.c:2072: warning: implicit declaration of function ‘XPAClose’
wrappers/xpa.c:2072: error: ‘struct __pyx_obj_3xpa_xpa’ has no member named ‘_xpa’
wrappers/xpa.c:2081: error: ‘struct __pyx_obj_3xpa_xpa’ has no member named ‘_template’
wrappers/xpa.c: In function ‘__pyx_pf_3xpa_3xpa_4get’:
wrappers/xpa.c:2176: error: ‘struct __pyx_obj_3xpa_xpa’ has no member named ‘_xpa’
wrappers/xpa.c:2176: error: ‘struct __pyx_obj_3xpa_xpa’ has no member named ‘_template’
wrappers/xpa.c:2176: error: too many arguments to function ‘__pyx_f_3xpa__get’
wrappers/xpa.c: In function ‘__pyx_pf_3xpa_3xpa_6set’:
wrappers/xpa.c:2285: error: ‘struct __pyx_obj_3xpa_xpa’ has no member named ‘_xpa’
wrappers/xpa.c:2285: error: ‘struct __pyx_obj_3xpa_xpa’ has no member named ‘_template’
error: command 'gcc' failed with exit status 1

Add a load_data() method

Display an image using an existing np.array, instead of going through a file. May exist but my observational powers are limited.

Add wrapper for rgbcube

you can call the xpa directly like this for loading RGBcubes:

import imexam
a=imexam.connect() #start ds9 window
a.window.xpa.set('rgb new') #open an rgb frame
a.window.xpa.set('rgb channel red')
a.load_fits('iabf01bzq_flt.fits') #load image to red
a.scale() #if you want
a.window.xpa.set('rgb channel green')
a.load_fits('iabf01bzq_flt.fits')
a.window.xpa.set('rgb channel blue')
a.load_fits('iabf01bzq_flt.fits')

save that image to fits:

a.window.xpa.set('save rgbimage rgb.fits')

In [39]: pyfits.info('rgb.fits')
Filename: rgb.fits
No. Name Type Cards Dimensions Format
0 PRIMARY PrimaryHDU 4 () uint8
1 SCI ImageHDU 107 (1014, 1014) float32
2 SCI ImageHDU 107 (1014, 1014) float32
3 SCI ImageHDU 107 (1014, 1014) float32

a convenince wrapper might look something like this, to load the respective images into R,G,B and scale them all with scale(), and align them in wcs

a.rgbload('iabf01bzq_flt.fits','iabf01bzq_flt.fits','iabf01bzq_flt.fits',sc
ale=True,lockwcs=True)
a.savergb('rgb.fits')

Installing from source in Windows 7 gives WinError

Using Anaconda on Windows 7 64-bit. Since AstroConda has no Windows distribution, my only option is to install from source, but even that failed.

>python setup.py install
Freezing version number to imexam\version.py
Compiling wrappers/xpa.pyx because it changed.
[1/1] Cythonizing wrappers/xpa.pyx
C:\...\setuptools-27.2.0-py3.5.egg\setuptools\dist.py:
rning: Normalizing '0.6.3dev263' to '0.6.3.dev263'
running install
running bdist_egg
running egg_info
creating imexam.egg-info
writing top-level names to imexam.egg-info\top_level.txt
writing dependency_links to imexam.egg-info\dependency_links.txt
writing imexam.egg-info\PKG-INFO
writing entry points to imexam.egg-info\entry_points.txt
writing manifest file 'imexam.egg-info\SOURCES.txt'
reading manifest file 'imexam.egg-info\SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching '*' under directory 'scripts'
warning: no previously-included files found matching 'cextern\xpa\man'
warning: no previously-included files found matching 'cextern\xpa\doc'
warning: no previously-included files found matching 'cextern\xpa\notes'
warning: no previously-included files matching '*.o' found anywhere in distribution
no previously-included directories found matching 'astropy_helpers\build'
no previously-included directories found matching 'docs\build'
no previously-included directories found matching 'docs\api'
no previously-included directories found matching 'build'
no previously-included directories found matching 'dist'
writing manifest file 'imexam.egg-info\SOURCES.txt'
installing library code to build\bdist.win-amd64\egg
running install_lib
running build_py
creating build
creating build\lib.win-amd64-3.5
creating build\lib.win-amd64-3.5\imexam
copying imexam\conftest.py -> build\lib.win-amd64-3.5\imexam
copying imexam\connect.py -> build\lib.win-amd64-3.5\imexam
copying imexam\ds9_viewer.py -> build\lib.win-amd64-3.5\imexam
copying imexam\ginga_viewer.py -> build\lib.win-amd64-3.5\imexam
copying imexam\imexamine.py -> build\lib.win-amd64-3.5\imexam
copying imexam\imexam_defpars.py -> build\lib.win-amd64-3.5\imexam
copying imexam\math_helper.py -> build\lib.win-amd64-3.5\imexam
copying imexam\util.py -> build\lib.win-amd64-3.5\imexam
copying imexam\version.py -> build\lib.win-amd64-3.5\imexam
copying imexam\xpa_wrap.py -> build\lib.win-amd64-3.5\imexam
copying imexam\_astropy_init.py -> build\lib.win-amd64-3.5\imexam
copying imexam\__init__.py -> build\lib.win-amd64-3.5\imexam
creating build\lib.win-amd64-3.5\imexam\tests
copying imexam\tests\setup_package.py -> build\lib.win-amd64-3.5\imexam\tests
copying imexam\tests\test_imexamine.py -> build\lib.win-amd64-3.5\imexam\tests
copying imexam\tests\__init__.py -> build\lib.win-amd64-3.5\imexam\tests
copying imexam\tests\coveragerc -> build\lib.win-amd64-3.5\imexam\tests
running build_ext
error: [WinError 2] The system cannot find the file specified

run autopep8

autopep8 --max-line-length=100 is usually sufficient but check the output.

Ds9 display closing seconds after opening

I am trying to execute this code in a script:

#Create region file
    master_list = []
    if man_sources:
        for ogc in man_sources:
            master_list.append('circle {} {} 10 #color=red'.format(ogc[0],ogc[1]))
    if casjobs_sources:
        for ogc in casjobs_sources:
            master_list.append('circle {}d {}d 12 #color=green'.format(ogc[0],ogc[1]))
    #DS9
    viewer=imexam.connect()
    viewer.load_fits(fits_image)
    viewer.scale()
    for reg in master_list:
        viewer.set_region(reg)

When I run the script it opens ds9 and then displays the circles for a millisecond and then quits. I have grabbed this newer version of imexam and the problem still persist.

I am using the 7.1 version of ds9.

connect without an argument raises an error

I noticed a strange error when I follow the instructions for Example 1 at http://imexam.readthedocs.org/imexam/examples.html . If I try to connect to ds9 via imexam.connect() without explicitly saying imexam.connect('ds9') (which is what Example 1 suggests is possible), I get a rather arcane error that I don't really understand. I do suspect it has something to do with the # this might be sketchy line right above, though ;)

In [2]: import imexam
In [3]: viewer = imexam.connect()
/Users/erik/miniconda3/envs/imexam/lib/python3.5/site-packages/imexam-0.5.3.dev0-py3.5-macosx-10.5-x86_64.egg/imexam/ds9_viewer.py:554: UserWarning: Starting ds9 failed
  warnings.warn("Starting ds9 failed")
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-3-6f0574bcd0ef> in <module>()
----> 1 viewer = imexam.connect()

/Users/erik/miniconda3/envs/imexam/lib/python3.5/site-packages/imexam-0.5.3.dev0-py3.5-macosx-10.5-x86_64.egg/imexam/connect.py in __init__(self, target, path, viewer, wait_time, quit_window)
     80         if 'ds9' in self._viewer:
     81             self.window = ds9(
---> 82                 target=target, path=path, wait_time=wait_time, quit_ds9_on_del=quit_window)
     83             self._event_driven_exam = False  # use the imexam loop
     84 

/Users/erik/miniconda3/envs/imexam/lib/python3.5/site-packages/imexam-0.5.3.dev0-py3.5-macosx-10.5-x86_64.egg/imexam/ds9_viewer.py in __init__(self, target, path, wait_time, quit_ds9_on_del)
    198 
    199             elif 'local' in self._xpa_method:
--> 200                 self._xpa_name, self._ds9_unix_name = self._run_unixonly_ds9()
    201 
    202             # tells xpa where to find sockets

/Users/erik/miniconda3/envs/imexam/lib/python3.5/site-packages/imexam-0.5.3.dev0-py3.5-macosx-10.5-x86_64.egg/imexam/ds9_viewer.py in _run_unixonly_ds9(self)
    562         # this might be sketchy
    563         try:
--> 564             file_list.remove(".IMT")  # should be in the directory, if not
    565         except (ValueError, IOError):
    566             warnings.warn("IMT not found in tmp, using first thing in list")

UnboundLocalError: local variable 'file_list' referenced before assignment

key bindings

Hi @sosey, we were wondering here at ESO how easy it is to change the keybindings

can't use integers to set zoom

In [4]: a.zoom(8)
ERROR: TypeError: argument of type 'int' is not iterable [imexam.ds9_basic]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-c79804709a0d> in <module>()
----> 1 a.zoom(8)

/Users/pickering/homebrew/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/imexam-0.1.dev-py2.7-macosx-10.8-x86_64.egg/imexam/connect.pyc in zoom(self, *args, **kwargs)
    266     def zoom(self, *args, **kwargs):
    267         """zoom to parameter which can be any recognized string"""
--> 268         self.window.zoom(*args, **kwargs)
    269 
    270     def zoomtofit(self):

/Users/pickering/homebrew/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/imexam-0.1.dev-py2.7-macosx-10.8-x86_64.egg/imexam/ds9_basic.pyc in zoom(self, par)
   1412 
   1413         """
-> 1414         if "close" in par:
   1415             try:
   1416                 self.set("zoom %s" % (str(par)))

TypeError: argument of type 'int' is not iterable

doing a.zoom("8") works properly, however.

Python 3 compatiliblity

I noticed at least one spot where the code isn't python 3 compatiable, an import of StringIO in imexamine.py. I didn't do a comprehensive check for other python 3 issues, so there may be others.

The current version of ginga breaks imexam

The current version of ginga does not work with imexam because the objects it calls were deleted or moved. I need to find the replacement and get it up and running again. The last version that worked was from april 15, 2015: 7528d3deb9f7839d0c58cd90f9e237a2cc116487

imexam window is shown black (and unresponsive)

I'm testing the following code in my elementary OS Loki (based on Ubuntu 16.04 65 bit)

import os
from os.path import join, realpath, dirname
import imexam

# Load data.
mypath = realpath(join(os.getcwd(), dirname(__file__)))
image_file = mypath + '/test.fits'

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

# Use ginga
# viewer = imexam.connect(viewer='ginga')
# Use DS9
viewer = imexam.connect()

viewer.load_fits(image_file)

viewer.imexam()

imexam is installed in a Python 3 conda environment:

$ conda info
Current conda install:

               platform : linux-64
          conda version : 4.3.16
       conda is private : False
      conda-env version : 4.3.16
    conda-build version : 2.0.8
         python version : 3.5.2.final.0
       requests version : 2.12.4
       root environment : /home/gabriel/anaconda3  (writable)
    default environment : /home/gabriel/anaconda3/envs/py3
       envs directories : /home/gabriel/anaconda3/envs
                          /home/gabriel/.conda/envs
          package cache : /home/gabriel/anaconda3/pkgs
                          /home/gabriel/.conda/pkgs
           channel URLs : http://ssb.stsci.edu/astroconda/linux-64
                          http://ssb.stsci.edu/astroconda/noarch
                          https://conda.anaconda.org/anaconda-fusion/linux-64
                          https://conda.anaconda.org/anaconda-fusion/noarch
                          https://repo.continuum.io/pkgs/free/linux-64
                          https://repo.continuum.io/pkgs/free/noarch
                          https://repo.continuum.io/pkgs/r/linux-64
                          https://repo.continuum.io/pkgs/r/noarch
                          https://repo.continuum.io/pkgs/pro/linux-64
                          https://repo.continuum.io/pkgs/pro/noarch
            config file : /home/gabriel/.condarc
           offline mode : False
             user-agent : conda/4.3.16 requests/2.12.4 CPython/3.5.2 Linux/4.4.0-72-generic debian/stretch/sid glibc/2.23
                UID:GID : 1000:1000

with the following packages installed

$ conda list
# packages in environment at /home/gabriel/anaconda3/envs/py3:
#
astropy                   1.3.2               np112py36_0  
bleach                    1.5.0                    py36_0  
brewer2mpl                1.4                      py36_0    bokeh
cycler                    0.10.0                   py36_0  
cython                    0.25.2                   py36_0  
dbus                      1.10.10                       0  
decorator                 4.0.11                   py36_0  
entrypoints               0.2.2                    py36_1  
expat                     2.1.0                         0  
fontconfig                2.12.1                        3  
freetype                  2.5.5                         2  
ggplot                    0.9.4                    py36_0    bokeh
ginga                     2.6.3                    py36_0    http://ssb.stsci.edu/astroconda
glib                      2.50.2                        1  
gst-plugins-base          1.8.0                         0  
gstreamer                 1.8.0                         0  
html5lib                  0.999                    py36_0  
icu                       54.1                          0  
imexam                    0.7.1                    py36_0    http://ssb.stsci.edu/astroconda
ipykernel                 4.6.0                    py36_0  
ipython                   5.3.0                    py36_0  
ipython_genutils          0.2.0                    py36_0  
ipywidgets                6.0.0                    py36_0  
jbig                      2.1                           0  
jinja2                    2.9.6                    py36_0  
jpeg                      9b                            0  
jsonschema                2.5.1                    py36_0  
jupyter                   1.0.0                    py36_3  
jupyter_client            5.0.1                    py36_0  
jupyter_console           5.1.0                    py36_0  
jupyter_core              4.3.0                    py36_0  
libffi                    3.2.1                         1  
libgcc                    5.2.0                         0  
libgfortran               3.0.0                         1  
libiconv                  1.14                          0  
libpng                    1.6.27                        0  
libsodium                 1.0.10                        0  
libtiff                   4.0.6                         3  
libxcb                    1.12                          1  
libxml2                   2.9.4                         0  
markupsafe                0.23                     py36_2  
matplotlib                2.0.0               np112py36_0  
mistune                   0.7.4                    py36_0  
mkl                       2017.0.1                      0  
mock                      2.0.0                    py36_0  
nbconvert                 5.1.1                    py36_0  
nbformat                  4.3.0                    py36_0  
networkx                  1.11                     py36_0  
nose                      1.3.7                    py36_1  
notebook                  5.0.0                    py36_0  
numpy                     1.12.0                   py36_0  
olefile                   0.44                     py36_0  
openssl                   1.0.2k                        0  
pandas                    0.19.2              np112py36_1  
pandocfilters             1.4.1                    py36_0  
path.py                   10.1                     py36_0  
patsy                     0.4.1                    py36_0  
pbr                       1.10.0                   py36_0  
pcre                      8.39                          1  
pexpect                   4.2.1                    py36_0  
photutils                 0.3.1                    py36_0    http://ssb.stsci.edu/astroconda
pickleshare               0.7.4                    py36_0  
pillow                    4.1.0                    py36_0  
pip                       9.0.1                    py36_1  
prompt_toolkit            1.0.14                   py36_0  
ptyprocess                0.5.1                    py36_0  
pygments                  2.2.0                    py36_0  
pyparsing                 2.1.4                    py36_0  
pyqt                      5.6.0                    py36_2  
python                    3.6.0                         0  
python-dateutil           2.6.0                    py36_0  
pytz                      2017.2                   py36_0  
pywavelets                0.5.2               np112py36_0  
pyzmq                     16.0.2                   py36_0  
qt                        5.6.2                         3  
qtconsole                 4.3.0                    py36_0  
qtpy                      1.2.1                    py36_0  
readline                  6.2                           2  
scikit-image              0.13.0              np112py36_0  
scipy                     0.19.0              np112py36_0  
setuptools                27.2.0                   py36_0  
simplegeneric             0.8.1                    py36_1  
sip                       4.18                     py36_0  
six                       1.10.0                   py36_0  
sqlite                    3.13.0                        0  
statsmodels               0.8.0               np112py36_0  
terminado                 0.6                      py36_0  
testpath                  0.3                      py36_0  
tk                        8.5.18                        0  
tornado                   4.4.2                    py36_0  
traitlets                 4.3.2                    py36_0  
wcwidth                   0.1.7                    py36_0  
wheel                     0.29.0                   py36_0  
widgetsnbextension        2.0.0                    py36_0  
xz                        5.2.2                         1  
zeromq                    4.1.5                         0  
zlib                      1.2.8                         3  

With both ginga and the default DS9 I get this

captura realizada el 2017-04-25 10 42 11

The window is completely unresponsive, and I have to force it to close. Any ideas how I can debug this?

m key raises AttributeError

After a quick connection, pressing "m" hits an attribute error: last of the traceback is below.

/Users/ely/anaconda3/envs/astroconda3/lib/python3.5/site-packages/imexam/imexamine.py in report_stat(self, x, y, data)
310 ymax = int(y + dist)
311 pstr = "[{0:d}:{1:d},{2:d}:{3:d}] {4:s}: {5:f}".format(
--> 312 xmin, xmax, ymin, ymax, stat.func_name, (stat(data[ymin:ymax, xmin:xmax])))
313 print(pstr)
314 logging.info(pstr)

AttributeError: 'function' object has no attribute 'func_name'

Matplotlib window doesn't update until "q"

I was just trying imexam right now with the latest conda (using the most recent matplotlib, astropy, and photutils), and, at least on my machine (OS X Yosemite), when I try any of the imexam plots, the matplotlib window pops up but does not render any plot - the cursor over the window yields only the "spinning beachball". I tried both the ds9 and ginga backends - in ginga's case it meant the image didn't appear at all, whereas for ds9 the ds9 behavior worked fine but none of the plots showed up.

My guess is this is due to some sort of threading behavior oddity, but I'm not well versed enough in how imexam talks back and forth with matplotlib to do more than guess...

ds9.view cannot handle cubes

If ds9.view is passed a cube, it fails. However, said cube can be loaded through reading a fits file.

>>> rancube = np.ones([50, 50, 50]) * np.random.rand(50)
>>> viewer.view(rancube)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/Users/eisenham/anaconda3/envs/jwstdevpy3/lib/python3.5/site-packages/imexam-0.7.2.dev307-py3.5-macosx-10.6-x86_64.egg/imexam/ds9_viewer.py in view(self, img)
   1706             try:
-> 1707                 img.shape = img.shape[-2:]
   1708             except:

ValueError: total size of new array must be unchanged

During handling of the above exception, another exception occurred:

UnsupportedImageShapeException            Traceback (most recent call last)
<ipython-input-25-97c9b56f0697> in <module>()
----> 1 viewer.view(rancube)

/Users/eisenham/anaconda3/envs/jwstdevpy3/lib/python3.5/site-packages/imexam-0.7.2.dev307-py3.5-macosx-10.6-x86_64.egg/imexam/connect.py in view(self, *args, **kwargs)
    487             self.window.view(args[0].data)  # when not specified
    488         else:
--> 489             self.window.view(*args, **kwargs)
    490
    491     def zoom(self, *args, **kwargs):

/Users/eisenham/anaconda3/envs/jwstdevpy3/lib/python3.5/site-packages/imexam-0.7.2.dev307-py3.5-macosx-10.6-x86_64.egg/imexam/ds9_viewer.py in view(self, img)
   1707                 img.shape = img.shape[-2:]
   1708             except:
-> 1709                 raise UnsupportedImageShapeException(repr(img.shape))
   1710
   1711             if img.dtype.byteorder in ["=", "|"]:

UnsupportedImageShapeException: (50, 50, 50)
>>> from astropy.io import fits
>>> fits.writeto('rancube.fits', rancube)
>>> viewer.load_fits('rancube.fits')
--------> OK

viewing and blinking fits images with ds9

This was moved over from discussion with @jehturner in astroconda/astroconda-contrib#183 (comment)

Oh, right. Why not? Sorry, I remember you talking about imexam, now that you mention it (and I think I tried it along time ago). Is this meant to supercede numdisplay then? One thing I do like is being able to display to ximtool as well, which I prefer for data inspection, but that's not important for these particular operational scripts.

Well, that didn't crash in my little test above (though I'd need to figure out how to deal with the started vs non-started ds9 in the script). Thanks for the suggestion.

Yup, it should fully replace numdisplay. Can ask what you're doing in ximtool that you prefer it for >inspection? If it's something not already in imexam, it could be added to the defaults or as a user >defined function. imexam replaces both numdisplay and the iraf imexamine functionality. There's more >info in the docs: http://imexam.rtfd.io/

you can grab the list of open windows using imexam.list_active_ds9() which returns a dictionary of >available windows, you can use the keys to connect, or if you've named them (ds9 -title junk), their >names, which are the first items in the list for each connection:
screen shot 2017-03-13 at 8 48 54 pm

Thanks for the extra info. It looks like load_fits() does allow just displaying an image without an interaction loop where needed, though if I subsequently do viewer.imexam() (on a MEF file) I get:

KeyError: 'HDUList indices must be integers, extension names as strings, or (extname, version) tuples; got None
I'm having trouble quickly spotting what is the right usage for specifying MEF extensions in the help (eg. the docstring for load_fits() has "*args, **kwargs" but doesn't explain what the options are).

Regarding ximtool, it's just a few bits of the user interface -- in particular, I really need ctrl-b / ctrl-f (along with "AReg") to flip back and forth instantaneously between image buffers for comparison. Blinking at a fixed rate doesn't cut it -- my brain doesn't work like that. That's a feature of the viewer rather than the display library though. This may be something that can be done in Ginga, or added to it, now that it can be installed more easily with Astroconda.

PS. DS9 does have , but it only cycles in one direction and is too slow, which isn't really useful (I did once hack it to cycle both ways but for some reason had to use a less convenient keystroke and the lag was still a problem).

Actually, FYI, I found load_mef_as_multi() but 1) our usual mode of use is to display a single, specified MEF extension at a time and 2) it still gives the same KeyError from the imexam() method (unless I'm doing something wrong). Sorry to deviate a bit from the issue subject...

If it thinks the file is MEF and you don't specify an extension it will try and load [1], if it thinks it's a >simple then the data in [0].

In [30]: viewer.load_fits('iacs01t4q_flt.fits')
In [31]: viewer.get_frame_info()
Out[31]:
{'extname': 'SCI',
'extver': 1,
'filename': '/Users/sosey/test_images/iacs01t4q_flt.fits',
'iscube': False,
'mef': True,
'naxis': 0,
'numaxis': 2,
'user_array': None}
you should also be able to:

viewer.load_fits('image.fits[1]')
viewer.load_fits('image.fits',extver=4)

I can't seem to replicate the imexam() issue with MEF files I have, but I'll open an issue over in the >imexam repo for updating the documentation to make using load_fits more clear. The function docs are >down a level: viewer.window.load_fits? because the connect() module works in composition to make it >a bit more flexible with different viewers and so you can use the imexamine stuff as a separate library. >(imexam also supports ginga widgets and its html5 display)

alas, I too miss the fast blinking. I get around that by calling viewer.frame('next') a bunch of times to go >back and forth. I'll think about linking this to an imexam option for the ds9 display.

Update imexam() to plot through a cube stack

Consider updating the imexam command so that when a slice of a cube is displayed you can make plots through the stack. Some thought should be put into how exactly this should work.

Don't run 2to3 for Python 3

As mentioned in astropy/package-template#93 it would be nice if Astropy and all affiliated packages worked with a single Python 2 / 3 codebase.

This is usually not hard to achieve ... set use_2to3=False in setup.py and then once run 2to3 on your package and manually go through the suggested changes to see which ones make sense.

@sosey I don't know, for imexam it might be difficult to get everything to work without 2to3?

AttributeError: module 'distutils.config' has no attribute 'ConfigParser'

I'm trying to install this package in a pyenv with Python 3.5.2 installed. This is what I get:

$ pip install imexam
Collecting imexam
  Using cached imexam-0.5.2.tar.gz
    Complete output from command python setup.py egg_info:
    The requested path 'astropy_helpers' for importing astropy_helpers does not exist, or does not contain a copy of the astropy_helpers pacakge.  Attempting download instead.
    Downloading astropy_helpers; run setup.py with the --offline option to force offline installation.
    /home/gabriel/.pyenv/versions/3.5.2/envs/photom-env/lib/python3.5/site-packages/matplotlib/font_manager.py:273: UserWarning: Matplotlib is building the font cache using fc-list. This may take a moment.
      warnings.warn('Matplotlib is building the font cache using fc-list. This may take a moment.')
    /home/gabriel/.pyenv/versions/3.5.2/envs/photom-env/lib/python3.5/site-packages/matplotlib/font_manager.py:273: UserWarning: Matplotlib is building the font cache using fc-list. This may take a moment.
      warnings.warn('Matplotlib is building the font cache using fc-list. This may take a moment.')
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-build-nwed80dj/imexam/setup.py", line 27, in <module>
        conf = config.ConfigParser()
    AttributeError: module 'distutils.config' has no attribute 'ConfigParser'

Use imexamine automatically given an image and a list of x,y coordinates

I'd like to use imexamine to emulate IRAF's psfmeasure task, which is useful to estimate the average FWHM of an image.

To do this, I need to pass to imexam an image, and a list of x,y star center coordinates. Then I have to emulate pressing the a key on each of those x,y coordinates, and log the results either to screen or a file.

Is this possible? Or must I press the a key manually star after star to obtain the estimated FWHMs?

VisibleDeprecationWarning from radial profile plot

Using the latest dev, I get this warning:

.../imexam-0.6.3.dev260-py3.5-linux-x86_64.egg/imexam/imexamine.py:923:
    VisibleDeprecationWarning: using a non-integer number instead of an integer
    will result in an error in the future
  chunk = data[y - delta:y + delta, x - delta:x + delta]

grab() sometimes returns an error

The primary symptom is:

/Users/anusha/astroconda/envs/aas229-workshop/lib/python3.5/subprocess.py in _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, start_new_session)
1549 else:
1550 err_msg += ': ' + repr(orig_executable)
-> 1551 raise child_exception_type(errno_num, err_msg)
1552 raise child_exception_type(err_msg)
1553

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

Small request for list_active_ds9()

Hello! I'm relatively new to using pyraf and imexam (and Github, to tell the truth), so please excuse me if this has been asked before or I'm going about any of this incorrectly. I have checked the previous issues and did not see it.

I noticed that list_active_ds9() prints the current DS9 session to the terminal. I wanted to be able to collect the XPA_METHOD via my script instead of manually finding it in my DS9 window, so I dug into my libraries and changed this code:

if find_xpans():
    try:
        ...
        if ..(stuff)
        else:
            print(sessions.decode())

To this:

if find_xpans():
    try:
        ...
        if ..(stuff)
        else:
            return sessions.decode()

This allows me to collect the string that list_active_ds9() spits out and parse it to grab the XPA_METHOD. This works for my purposes, though I realize it may cause issues if users have multiple DS9 windows open. Would you consider adding perhaps a toggle-able option to either return the values or print the values, depending on user needs? If you like the idea, I can contribute the code change if that is allowed on this repository.

Thanks for this very helpful module!

get_data() doesn't work with an array displayed using view()

get_data() returns nothing when looking at an array in the frame which was created in memory and sent to ds9 with the view() method. This is because the array was created by the user and is already sitting around in memory for them. Return a nice reminder print statement in this case. Another side affect is that imexam() doesn't work on the array, not sure how to get around that one yet.

Crash on Mac

@sosey This looks really neat ... I'd really like to try this (I'm getting involved in photutils development).

Unfortunately it crashes for me with Python 2.7 on my Macbook.

I get this warning during the build, which might be the cause?

tcl.c: In function 'XPANew_Tcl':
tcl.c:397:11: warning: assignment from incompatible pointer type [enabled by default]
     sproc = XPATclSend;

Full build log here: https://gist.github.com/cdeil/9d826c25c9df9bc9440b#file-gistfile1-txt-L231

To reproduce the crash:

$ cd /tmp
$ python -c 'import imexam; imexam.list_active_ds9()'
Abort trap: 6

Crash report here: https://gist.github.com/cdeil/6e07a66c51e536ee9308#file-gistfile1-txt-L31

Feel free to ignore this issue if you're not interested in making this work on Mac for now. :-)

Sphinx warning

There is a minor Sphinx warning that is causing the documentation build to fail on Travis:

/home/travis/build/spacetelescope/imexam/docs/imexam/description.rst:198: ERROR: Unexpected indentation.

Calling setlog successively with different filenames does not actually open new files

Hello again! I have written a script that auto-opens FIT files from various subdirectories in a directory and cycles through them and starts imexam for me, allowing me to use tasks. I have set the script to log anything I do to a log file. I would like to have different log files for every image, but even though I update the log file name for each new image, it doesn't actually save to that new file (even though it prints a message saying it does).

My code:

XPA_METHOD = whatever_it_is

v = imexam.connect(XPA_METHOD)

imgdirlists = [ ['path/to/folder', ['img1.FIT', 'img2.FIT]], 
                          ['path/to/folder2', ['img3.FIT', 'img4.FIT']] ] # etc

for sublist in imgdirlists:
    imgnames = sublist[1]
    curdir = sublist[0]
    if sublist[1]:    # makes sure the directory isn't empty, e.g. a top-level
        for image in imgnames:
            path = "{}/{}".format(curdir, image)
            v.load_fits(path)
            # set the log file name. use of [:-4] just omits the .FIT extension.
            v.setlog(filename="{}_sky".format(image[:-4]), on=True)
            v.imexam()
            # I tried the following to see if it helped, but it did not.
            v.setlog(filename="{}_sky".format(image[:-4]), on=False)
    else:
        pass

This puts out a file with the name of the first image I started on, filled with data like this:

_run_imexam
Current image /path/to/the/photo/14-57-57-755.FIT

(task results 1)
(task results 2)
...

_run_imexam
Current image /path/to/the/photo/14-57-41-217.FIT

(task results 1)
(task results 2)
...

The goal of course is to have each of those image lines and their results be in separate files. I tried looking at the util.py and connect.py code to see if I could fix it myself, but I'm afraid I don't know much about logging, and it wasn't clear to me where the issue was. It seems to be maybe related to the caveat in the docstring for set_logging:

Notes
-----
basicConfig defaults to opening the file in append mode
There's still an issue here that if the user deletes the
log file and then continues on with functions which log
information, no new file is opened again and nothing gets written

Has this been noticed by others, or are there any suggestions as to fixing it?

thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.