Getting a very blue image when trying to stack three bands of FITS images, not sure why blue is coming across more than the others and unsure how to adjust individually
import numpy as np
from astropy.io import fits
from astropy.visualization import SqrtStretch
from astropy.visualization import ZScaleInterval
from astropy.visualization import make_lupton_rgb
from matplotlib import pyplot as plt
forCasting = np.float_()
r=fits.open('...Directory_to_file/Horsehead_Red.fts')[0].data
g=fits.open('...Directory_to_file/Horsehead_Green.fts')[0].data
b=fits.open('...Directory_to_file/Horsehead_Blue.fts')[0].data
r = np.array(r,forCasting)
g = np.array(g,forCasting)
b = np.array(b,forCasting)
stretch = SqrtStretch() + ZScaleInterval()
r = stretch(g)
g = stretch(b)
b = stretch(r)
plt.imshow(r, origin='lower')
plt.imshow(g, origin='lower')
plt.imshow(b, origin='lower')
lo_val, up_val = np.percentile(np.hstack((r.flatten(), g.flatten(), b.flatten())), (10, 80))
stretch_val = up_val - lo_val
rgb_default = make_lupton_rgb(r, g, b, minimum=lo_val, stretch=stretch_val, Q=0, filename="provafinale.png")
plt.imshow(rgb_default, origin='lower')
plt.show()
The resulting image in question:
Related
Seaborn offers the possibility to invert the axis of an image. I would like to do the same with PIL. Here is my code.
# Imports
import seaborn as sns; sns.set_theme()
import matplotlib.pyplot as plt
import numpy as np
import numpy as np; np.random.seed(0)
from PIL import Image
import random
# Arrays
r = []
g = []
b = []
for i in range(200):
r.append(random.sample(range(0, 255), 200))
g.append(random.sample(range(0, 255), 200))
b.append(random.sample(range(0, 255), 200))
# Change color of the left part of the image
r = np.array(r)
r[:, 0:10]=0
# Change color of the right part of the image
r = np.array(r)
r[:, -10:-1]=150
g = np.array(g)
g[:, -10:-1]=150
# Plot seaborn heatmap
fig, ax = plt.subplots()
sax = sns.heatmap(r)
sax.invert_xaxis()
sax.invert_xaxis() inverts the x-axis of the plot.
I would like to do the same with pillow. I have been google it for a long time without finding anything.
Here is my rgb pillow image.
rgbarr = np.zeros((200,200,3), 'uint8')
rgbarr[..., 0] = np.array(r)
rgbarr[..., 1] = np.array(g)
rgbarr[..., 2] = np.array(b)
img = Image.fromarray(rgbarr)
img
opencv possibility would also be welcome.
I think you just want to flip it:
im_flipped = im.transpose(method=Image.FLIP_LEFT_RIGHT)
I have a Seaborn Joinplot on which I want to draw an empty circle which will mark a certain diameter around the (0,0) point. Something like this:
How can it be done?
ax_joint.plot will do the job.
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style="white", color_codes=True)
tips = sns.load_dataset("tips")
a = sns.jointplot(x="total_bill", y="tip", data=tips)
a.ax_joint.plot([15],[3],'o',ms=60,mec='r',mfc='none')
I found the answer:
a = sns.jointplot(x=var_x, y=var_y, data=my_df)
a.ax_joint.plot([0],[0],'o',ms=60 , mec='r', mfc='none')
There is a dirty way to do it: generate the circle from equation and then plot that. I'm sure there are more sophisticated solutions, but I couldn't figure it out yet. This is by modifying the data of sns.JointGrid.
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
sns.set(style="ticks")
R = 8 # radius
d = np.linspace(0,2*np.pi, 400) # some data to draw circle
def circle(d, r):
# x and y from the equation of a circle
return r*np.cos(d), r*np.sin(d)
rs = np.random.RandomState(11)
x = rs.gamma(2, size=1000)
y = -.5 * x + rs.normal(size=1000)
#graph your data
graph = sns.jointplot(x, y, kind="hex", color="#4CB391")
# creating the circle
a, b = circle(d, R)
#graphing it
graph.x = a
graph.y = b
graph.plot_joint(plt.plot)
plt.show()
I am trying to create a colormap from an image. This works fine using a continuous range but I'm trying to reduce the amount of colors by a discrete factor.
I have tried to do this using 10 colors via the following code but all I get is red?
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
cim = plt.imread("https://i.stack.imgur.com/4q2Ev.png")
cim = cim[cim.shape[0]//2, 8:740, :]
cmap = mcolors.ListedColormap(cim)
norm = mcolors.BoundaryNorm([0,1,2,3,4,5,6,7,8,9,10], cmap.N)
X = np.random.rand(10,10)
Y = np.random.rand(10,10)
plt.contourf(X, Y, levels=100, cmap=cmap, norm = norm)# alpha = 0.8)
plt.colorbar()
If you only want 10 colors in your colormap, you can create it with just those 10 colors:
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
cim = plt.imread("https://i.stack.imgur.com/4q2Ev.png")
cim = cim[cim.shape[0]//2, 8:740, :]
cim_10 = cim[cim.shape[0] // 9 * np.arange(10)] # array of 10 colors
cmap = mcolors.ListedColormap(cim_10)
print(cmap.N) # prints 10
X = np.random.rand(10,10)
plt.contourf(X, cmap=cmap, levels=np.linspace(0, 1, 11))
plt.colorbar()
plt.show()
I have a .png image with alpha channel and a random pattern generated with numpy.
I want to supperpose both images using matplotlib. The bottom image must be the random pattern and over this, I want to see the second image (attached in the end of the post).
The code for both images is the following:
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
# Random image pattern
fig = plt.subplots(figsize = (20,4))
x = np.arange(0,2000,1)
y = np.arange(0,284,1)
X,Y = np.meshgrid(x,y)
Z = 0.6+0.1*np.random.rand(284,2000)
Z[0,0] = 0
Z[1,1] = 1
# Plot the density map using nearest-neighbor interpolation
plt.pcolormesh(X,Y,Z,cmap = cm.gray)
The result is the following image:
To import the image, I use the following code:
# Sample data
fig = plt.subplots(figsize = (20,4))
# Plot the density map using nearest-neighbor interpolation
plt.imread("good_image_2.png")
plt.imshow(img)
print(img.shape)
The image is the following:
Thus, the final result that I want is:
You can make an image-like array for Z and then just use imshow to display it before the image of the buttons, etc. Note that this only works because your png has an alpha channel.
Code:
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
# Plot the density map using nearest-neighbor interpolation
img = plt.imread("image.png")
(xSize, ySize, cSize) = img.shape
x = np.arange(0,xSize,1)
y = np.arange(0,ySize,1)
X,Y = np.meshgrid(x,y)
Z = 0.6+0.1*np.random.rand(xSize,ySize)
Z[0,0] = 0
Z[1,1] = 1
# We need Z to have red, blue and green channels
# For a greyscale image these are all the same
Z=np.repeat(Z,3).reshape(xSize,ySize,3)
fig = plt.figure(figsize=(20,8))
ax = fig.add_subplot(111)
ax.imshow(Z, interpolation=None)
ax.imshow(img, interpolation=None)
fig.savefig('output.png')
Output:
You can also turn off axes if you prefer.
ax.axis('off')
I have the nice hexbin plot below, but I'm wondering if there is any way to get hexbin into an Aitoff projection? The salient code is:
import numpy as np
import math
import matplotlib.pyplot as plt
from astropy.io import ascii
filename = 'WISE_W4SNRge3_and_W4MPRO_lt_6.0_RADecl_nohdr.dat'
datafile= path+filename
data = ascii.read(datafile)
points = np.array([data['ra'], data['dec']])
color_map = plt.cm.Spectral_r
points = np.array([data['ra'], data['dec']])
xbnds = np.array([ 0.0,360.0])
ybnds = np.array([-90.0,90.0])
extent = [xbnds[0],xbnds[1],ybnds[0],ybnds[1]]
fig = plt.figure(figsize=(6, 4))
ax = fig.add_subplot(111)
x, y = points
gsize = 45
image = plt.hexbin(x,y,cmap=color_map,
gridsize=gsize,extent=extent,mincnt=1,bins='log')
counts = image.get_array()
ncnts = np.count_nonzero(np.power(10,counts))
verts = image.get_offsets()
ax.set_xlim(xbnds)
ax.set_ylim(ybnds)
plt.xlabel('R.A.')
plt.ylabel(r'Decl.')
plt.grid(True)
cb = plt.colorbar(image, spacing='uniform', extend='max')
plt.show()
and I've tried:
plt.subplot(111, projection="aitoff")
before doing the plt.hexbin command, but which only gives a nice, but blank, Aitoff grid.
The problem is that the Aitoff projection uses radians, from -π to +π. Not degrees from 0 to 360. I use the Angle.wrap_at function to achieve this, as per this Astropy example (which essentially tells you how to create a proper Aitoff projection plot).
In addition, you can't change the axis limits (that'll lead to an error), and shouldn't use extent (as ImportanceOfBeingErnest's answer also states).
You can change your code as follows to get what you want:
import numpy as np
import matplotlib.pyplot as plt
from astropy.io import ascii
from astropy.coordinates import SkyCoord
from astropy import units
filename = 'WISE_W4SNRge3_and_W4MPRO_lt_6.0_RADecl_nohdr.dat'
data = ascii.read(filename)
coords = SkyCoord(ra=data['ra'], dec=data['dec'], unit='degree')
ra = coords.ra.wrap_at(180 * units.deg).radian
dec = coords.dec.radian
color_map = plt.cm.Spectral_r
fig = plt.figure(figsize=(6, 4))
fig.add_subplot(111, projection='aitoff')
image = plt.hexbin(ra, dec, cmap=color_map,
gridsize=45, mincnt=1, bins='log')
plt.xlabel('R.A.')
plt.ylabel('Decl.')
plt.grid(True)
plt.colorbar(image, spacing='uniform', extend='max')
plt.show()
Which gives
I guess your problem lies in the use of the extent which is set to something other than the range of the spherical coordinate system.
The following works fine:
import matplotlib.pyplot as plt
import numpy as np
ra = np.linspace(-np.pi/2.,np.pi/2.,1000)
dec = np.sin(ra)*np.pi/2./2.
points = np.array([ra, dec])
plt.subplot(111, projection="aitoff")
color_map = plt.cm.Spectral_r
x, y = points
gsize = 45
image = plt.hexbin(x,y,cmap=color_map,
gridsize=45,mincnt=1,bins='log')
plt.xlabel('R.A.')
plt.ylabel(r'Decl.')
plt.grid(True)
cb = plt.colorbar(image, spacing='uniform', extend='max')
plt.show()