How do you log stretch a FITS image and change its contrast? - python

I'm trying to use astropy 2.0.11 with python 2.7.15 to edit a fits image by applying a log stretch to it and change the contrast, and I have't been able to figure it out.
I've been trying to follow the tutorials on the astropy website for opening and manipulating fits files, but I'm wondering if the tutorials will only work for the latest version of astropy and on python 3?
Sorry about the organization of my code. This is prototype code and I'm just trying to test a few things and get this to work.
import time
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
import astropy.visualization
from astropy.io import fits
from astropy.utils.data import download_file
from astropy.visualization import astropy_mpl_style
plt.style.use(astropy_mpl_style)
from astropy.utils.data import get_pkg_data_filename
def main():
#My own fits file
#fitsImage = get_pkg_data_filename("C:\\20180807T000456.fits")
fitsImage = download_file('http://data.astropy.org/tutorials/FITS-images/HorseHead.fits', cache=True )
hdu_list = fits.open(fitsImage)
hdu_list.info()
#norm = ImageNormalize(stretch=LogStretch())
image_data = fits.getdata(fitsImage)
print(type(image_data))
print(image_data.shape)
hdu_list.close()
plt.figure()
plt.imshow(image_data, cmap='gray', norm=LogNorm())
plt.colorbar()
# I chose the tick marks based on the histogram above
cbar = plt.colorbar(ticks=[5.e3,1.e4,2.e4])
cbar.ax.set_yticklabels(['5,000','10,000','20,000'])
time.sleep(10)
I am also unable to get the image to display with the plt.imshow()
Any insight would be helpful

You're so close! I ran your code in Python 2.7 and all you need to do is add
plt.show()
before time.sleep(10) (any reason you're including this?) and you get
Also, I don't think you need to include the colorbar and yticklabels, plt.imshow automatically adds the colorbar with the lognorm scale (I commented that section out when I got the image).

Related

plotting streamplot is so slow in python3

I am using Anaconda, and I think this problem is even before I use Anaconda.
Everytime I want to plot streamline with basemap, it takes a very long time to plot one figure.
Here is an example:
import netCDF4 as nc
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap
fuv = nc.Dataset('~/era5_uv850_20200601_00_01.nc')
uwnd = fuv.variables['u']
vwnd = fuv.variables['v']
uwnd = uwnd[0,:,:]
vwnd = vwnd[0,:,:]
lon= fuv.variables['longitude']
lat= fuv.variables['latitude']
map = Basemap(projection='cyl',llcrnrlat= 0.,urcrnrlat=20.,llcrnrlon=90.5,urcrnrlon=120.5,resolution='i')
x,y=map(*np.meshgrid(lon,lat))
plt.clf()
map.streamplot(x,y,uwnd,vwnd,30)
map.drawcoastlines()
map.drawcountries()
plt.show()
The data from ERA5 webpage: Copernicus Data Storage
or you can download it here: WeTransfer Link
Is the slowness a common issue?

How to show single colorbar in loop by Python?

I've tried to plot images of my loaded 2D data (512x512 pixels) in a loop by matplotlib with Python3. But it turns out to show weird images with multiple colorbars. Here is my code:
import numpy as np
import sys
import os
from load_images import load, File
import matplotlib.pyplot as plt
from matplotlib import cm
arr_spe = [x for x in os.listdir() if x.endswith(".SPE")]
for x in arr_spe:
try:
dat = load(x)
plt.imshow(dat,cmap=cm.jet, vmax = 2000)
plt.colorbar()
plt.savefig(x[:-4]+'.png', dpi=500, bbox_inches='tight')
except ValueError as error:
print('ValueError(empty)-'+x)
I use the code to load my data in the following link: Reading SPE file from CCD camera by naming the code as load_images.py.
And I got many images like
Does anybody have ideas to solve this issue? Just simply show single colorbar in an image

Plot a FITS image over a grid of the entire sky

I would like to plot a FITS image over a sketch of the entire sky.
I got this far in plotting the entire sky:
import matplotlib.pyplot as plt
from astropy.utils.data import get_pkg_data_filename
from astropy.io import fits
image_file = get_pkg_data_filename('tutorials/FITS-images/HorseHead.fits')
image_data = fits.getdata(image_file, ext=0)
plt.subplot(111, projection='aitoff')
plt.grid(True)
plt.imshow(image_data, cmap='gray')
plt.show()
But I can't seem to get the FITS image properly aligned with the grid
The above code results in the following
But I'm trying to get something more like
where the blue square is the actual position of the image in image_file
The image_data is just an array of pixel values, and doesn't actually contain any information about the positions and orientations of the pixels on a sky map. You have to extract that information from the FITS file too.
An example would be (based in information from here and here):
import matplotlib.pyplot as plt
from astropy.utils.data import get_pkg_data_filename
from astropy.io import fits
from astropy.wcs import WCS
from astropy.visualization.wcsaxes.frame import EllipticalFrame
image_file = get_pkg_data_filename('tutorials/FITS-images/HorseHead.fits')
image_header = fits.open(image_file)[0].header # extract header info
image_data = fits.getdata(image_file, ext=0)
# use the WCS class to get coordinate info and projection axes to use
wcs = WCS(image_header)
# make the axes using the EllipticalFrame class
ax = plt.subplot(projection=wcs, frame_class=EllipticalFrame)
# add the image
im = ax.imshow(image_data, origin='lower')
# add a grid
overlay = ax.get_coords_overlay('fk5')
overlay.grid(color='white', ls='dotted')
As the particular image example doesn't extend across the whole sky you'll only see a small patch (but you can extend the plot using ax.set_xlim() and ax.set_ylim() as required, although I'm not sure what the units are, and it's also worth noting that this image actually just covers a very small patch of sky), but if your image was over the whole sky it would look like an Aitoff projection as shown here.
I think this only works with the latest version of astropy (v3.1), Matplotlib (v3.0.2), and therefore requires Python >= 3.5.
You may also want to look at healpy, although that can't read in the astropy example FITS file.

Imshow doesn't display image when used with astropy

I am running into a problem viewing images with astropy. Here is my code:
from astropy.io import fits
import matplotlib.pyplot as plt
hdu_list=fits.open("500m2deep.fit")
image_data=hdu_list[0].data
hdu_list.close()
plt.imshow(image_data,cmap='gray')
plt.show()
Opening the file works fine, I can display the entries of image_data and alike. But the picture doesn't show if I use imshow. It displays the following error:
C:\Python27\lib\site-packages\IPython\core\formatters.py:239: FormatterWarning: Exception in image/png formatter:
FormatterWarning,
If I use, as suggested on some sites, %matplotlib inline, or something similar, this error disappears, but no image shows at all, the program runs, terminates, no picture pops up. I also tried adding something like plt.figure() before imshow() but that doesn't help either.
This happens if I use Spyder, Ipython, or Ipython Notebook. I am using the newest version of python(x,y) for all of this.
How can I display the pictures?
Maybe too late to be a useful solution for you, but mayb someone else can profit.
I recently ran into the same issue on Ubuntu 16.04, python 3.5 and Astropy 1.1.1 using the sample code from the astropy website (first and last line added by me), which is:
#!/usr/bin/python3
import matplotlib.pyplot as plt
from astropy.wcs import WCS
from astropy.io import fits
from astropy.utils.data import get_pkg_data_filename
filename = get_pkg_data_filename('galactic_center/gc_msx_e.fits')
hdu = fits.open(filename)[0]
wcs = WCS(hdu.header)
plt.subplot(projection=wcs)
plt.imshow(hdu.data, vmin=-2.e-5, vmax=2.e-4, origin='lower')
plt.grid(color='white', ls='solid')
plt.xlabel('Galactic Longitude')
plt.ylabel('Galactic Latitude')
plt.show()
It did open the figure window, but did not display any image data.
Updating the astropy version to 1.3 (which also updated numpy to 1.11.3) fixed the issue. Now it works fine.

matplotlib fails to output EPS figure with usetex = True

I am trying to output (savefig) matplotlib figures as EPS; however, it seems there is a conflict when using the LaTeX rendering AND saving EPS figures. For example, the following code produces a good EPS figure:
import matplotlib.pyplot as plt
import numpy as np
plt.figure()
plt.plot(np.random.rand(100))
plt.savefig('plot.eps')
whereas this code produces an EPS figure that can not be viewed; my document viewer (Ubuntu's Evince) continuously says "Loading..."
import matplotlib.pyplot as plt
import numpy as np
plt.rc('text', usetex = True)
plt.figure()
plt.plot(np.random.rand(100))
plt.savefig('plot.eps')
Is there a known issue when combining these two options? Is there any kind of work around (aside from saving as PDF or saving as PDF then converting to EPS)?
The only solution I could find was to update matplotlib from 1.2.1 to 1.3.1. Now it works without problems.

Categories