astropy / photutils

Astropy package for source detection and photometry. Maintainer: @larrybradley
https://photutils.readthedocs.io
BSD 3-Clause "New" or "Revised" License
250 stars 138 forks source link

ImageNormalize returns TypeError: must be type, not classobj #247

Closed kpardeshi closed 9 years ago

cdeil commented 9 years ago

@kpardeshi - We need more information to see if this is a problem in your script or a bug in photutils.

The best would be if you can produce a standalone script that results in this error and post it here with the traceback (i.e. the full error message from the console) you get. If this is too time-consuming because you only get this error under certain circumstances when running a large script, please post at least the traceback.

kpardeshi commented 9 years ago

From the 'Background and Background Noise Estimation' section of the documentation:

from photutils.datasets import make_100gaussians_image
data = make_100gaussians_image()

from photutils.extern.imageutils.visualization import SqrtStretch
from photutils.extern.imageutils.visualization.mpl_normalize import ImageNormalize
import matplotlib.pylab as plt
norm = ImageNormalize(stretch=SqrtStretch())
plt.imshow(data, origin='lower', cmap='Greys_r', norm=norm)

the penultimate command returns the said TypeError in the title. 
  File "/Library/Python/2.7/site-packages/photutils/extern/imageutils/visualization/mpl_normalize.py", line 36, in __init__
    super(ImageNormalize, self).__init__(vmin=vmin, vmax=vmax, clip=clip)
TypeError: must be type, not classobj

(Sorry I am new to GitHub, not sure how else to submit this script). Hope this helps.

astrofrog commented 9 years ago

@kpardeshi just for future, you can include the traceback inside triple quotes:

traceback here

and it makes it more readable (I added this to your comment)

cdeil commented 9 years ago

Hmmm ... this works for me with matplotlib 1.4.2 ... what version of matplotlib do you have? You can use this command to find out:

python -c 'import matplotlib; print(matplotlib.__version__)'

The ImageNormalize class is now available in Astropy core and in #246 I'll change the imports to use that version. This might resolve the issue or it might not.

larrybradley commented 9 years ago

This works fine for me too (also with matplotlib 1.4.2).

This exception is raised when using super() with old-style classes. There are no old-style classes in photutils. However, ImageNormalize is a subclass of matplotlib.colors.Normalize. So I suspect that this is due to an old version of matplotlib.

astrofrog commented 9 years ago

In that case, we could consider getting rid of super and just doing Normalize.__init__(self, ...).

kpardeshi commented 9 years ago

Unfortunately I still get the error with matplotlib version 1.6.2:

 import matplotlib.pylab as plt
 print(plt.__version__)
'1.6.2'

When I run photutils.test(); along with the error in ImageNormalize I get the following error in 'test_aperture_plots[aperture_class4-params4]'

_________________ test_aperture_plots[aperture_class4-params4] _________________

aperture_class = <class 'photutils.aperture_core.RectangularAperture'>
params = (5, 8, 0.7853981633974483)

    @pytest.mark.skipif('not HAS_MATPLOTLIB')
    @pytest.mark.parametrize(('aperture_class', 'params'), TEST_APERTURES)
    def test_aperture_plots(aperture_class, params):
        # This test should run without any errors, and there is no return value

        # TODO for 0.2: check the content of the plot

        aperture = aperture_class((20., 20.), *params)
>       aperture.plot()

/Library/Python/2.7/site-packages/photutils/tests/test_aperture_photometry.py:73: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <photutils.aperture_core.RectangularAperture object at 0x1070cf6d0>
ax = <matplotlib.axes.AxesSubplot object at 0x106f61410>, fill = False
source_id = None, kwargs = {'fill': False}
plt = <module 'matplotlib.pyplot' from '/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/pyplot.pyc'>
mpatches = <module 'matplotlib.patches' from '/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/patches.pyc'>
positions = array([[ 21.06066017,  15.40380592]]), hw = 2.5, hh = 4.0
sint = 0.7071067811865475, cost = 0.7071067811865476

    def plot(self, ax=None, fill=False, source_id=None, **kwargs):

        import matplotlib.pyplot as plt
        import matplotlib.patches as mpatches

        kwargs['fill'] = fill

        if ax is None:
            ax = plt.gca()

        if source_id is None:
            positions = self.positions
        else:
            positions = self.positions[np.atleast_1d(source_id)]

        hw = self.w / 2.
        hh = self.h / 2.
        sint = math.sin(self.theta)
        cost = math.cos(self.theta)
        dx = (hh * sint) - (hw * cost)
        dy = -(hh * cost) - (hw * sint)
        positions = positions + np.array([dx, dy])
        theta_deg = self.theta * 180. / np.pi
        for position in positions:
            patch = mpatches.Rectangle(position, self.w, self.h, theta_deg,
>                                      **kwargs)
E           TypeError: __init__() takes exactly 4 arguments (6 given)

/Library/Python/2.7/site-packages/photutils/aperture_core.py:921: TypeError

They may be related because this also requires matplotlib. I also get an error in 'test_centroids_withmask' but it has to do with numpy so I will post it in another thread.

astrofrog commented 9 years ago

@kpardeshi - just to double check, what do you get if you run:

import numpy as np

data = np.arange(100).reshape(10,10)

from astropy.visualization import SqrtStretch
from astropy.visualization.mpl_normalize import ImageNormalize

import matplotlib.pylab as plt

norm = ImageNormalize(stretch=SqrtStretch())
plt.imshow(data, origin='lower', cmap='Greys_r', norm=norm)

? (note that this now uses ImageNormalize from Astropy instead of photutils.

astrofrog commented 9 years ago

This can't be right:

 import matplotlib.pylab as plt
 print(plt.__version__)
'1.6.2'

The latest stable version of matplotlib is 1.4.2 - not sure what could be going on there!

In any case, I've reproduced the bug here with matplotlib < 1.2 because indeed Normalize used to be an old-style class. I'll open a PR to Astropy to fix this before 1.0 final.

astrofrog commented 9 years ago

I've opened a fix for Astropy: https://github.com/astropy/astropy/pull/3413 - this should make 1.0