def disp(iimg, label = "", gray=False):
""" Display an image using pylab
"""
try:
import pylab
dimage = iimg.copy()
if iimg.ndim==3:
dimage[...,0] = iimg[...,2]
dimage[...,2] = iimg[...,0]
pylab.imshow(dimage, interpolation='none')
if gray: pylab.gray()
#pylab.gca().format_coord = format_coord
pylab.text(1500, -30, label)
pylab.axis('off')
pylab.show()
except ImportError:
print "Module pylab not available"
python类axis()的实例源码
def edgescatter(self, ps):
for ei,X in enumerate(self.edges):
i,j = X[:2]
matchdRA, matchdDec = X[10:12]
mu = X[9]
A = self.alignments[ei]
plt.clf()
if len(matchdRA) > 1000:
plothist(matchdRA, matchdDec, 101)
else:
plt.plot(matchdRA, matchdDec, 'k.', alpha=0.5)
plt.axvline(0, color='0.5')
plt.axhline(0, color='0.5')
plt.axvline(mu[0], color='b')
plt.axhline(mu[1], color='b')
for nsig in [1,2]:
X,Y = A.getContours(nsigma=nsig)
plt.plot(X, Y, 'b-')
plt.xlabel('delta-RA (arcsec)')
plt.ylabel('delta-Dec (arcsec)')
plt.axis('scaled')
ps.savefig()
def plotaffine(aff, RR, DD, exag=1000, affineOnly=False, doclf=True, **kwargs):
import pylab as plt
if doclf:
plt.clf()
if affineOnly:
dr,dd = aff.getAffineOffset(RR, DD)
else:
rr,dd = aff.apply(RR, DD)
dr = rr - RR
dd = dd - DD
#plt.plot(RR, DD, 'r.')
#plt.plot(RR + dr*exag, DD + dd*exag, 'bx')
plt.quiver(RR, DD, exag*dr, exag*dd,
angles='xy', scale_units='xy', scale=1,
pivot='middle', color='b', **kwargs)
#pivot='tail'
ax = plt.axis()
plt.plot([aff.getReferenceRa()], [aff.getReferenceDec()], 'r+', mew=2, ms=5)
plt.axis(ax)
esuf = ''
if exag != 1.:
esuf = ' (x %g)' % exag
plt.title('Affine transformation found' + esuf)
def mahalanobis_distsq(X, mu, C):
#print 'X', X.shape
#print 'mu', mu.shape
#print 'C', C.shape
assert(C.shape == (2,2))
det = C[0,0]*C[1,1] - C[0,1]*C[1,0]
Cinv = np.array([[ C[1,1]/det, -C[0,1]/det],
[-C[1,0]/det, C[0,0]/det]])
#print 'Cinv', Cinv.shape
#print 'Cinv * C:', np.dot(Cinv, C)
#print 'C * Cinv:', np.dot(C, Cinv)
d = X - mu
#print 'd', d.shape
Cinvd = np.dot(Cinv, d.T)
#print 'Cinvd', Cinvd.shape
M = np.sum(d * Cinvd.T, axis=1)
#print 'M', M.shape
return M
def plot_rectified(self):
import pylab
pylab.title('rectified')
pylab.imshow(self.rectified)
for line in self.vlines:
p0, p1 = line
p0 = self.inv_transform(p0)
p1 = self.inv_transform(p1)
pylab.plot((p0[0], p1[0]), (p0[1], p1[1]), c='green')
for line in self.hlines:
p0, p1 = line
p0 = self.inv_transform(p0)
p1 = self.inv_transform(p1)
pylab.plot((p0[0], p1[0]), (p0[1], p1[1]), c='red')
pylab.axis('image');
pylab.grid(c='yellow', lw=1)
pylab.plt.yticks(np.arange(0, self.l, 100.0));
pylab.xlim(0, self.w)
pylab.ylim(self.l, 0)
def plot_original(self):
import pylab
pylab.title('original')
pylab.imshow(self.data)
for line in self.lines:
p0, p1 = line
pylab.plot((p0[0], p1[0]), (p0[1], p1[1]), c='blue', alpha=0.3)
for line in self.vlines:
p0, p1 = line
pylab.plot((p0[0], p1[0]), (p0[1], p1[1]), c='green')
for line in self.hlines:
p0, p1 = line
pylab.plot((p0[0], p1[0]), (p0[1], p1[1]), c='red')
pylab.axis('image');
pylab.grid(c='yellow', lw=1)
pylab.plt.yticks(np.arange(0, self.l, 100.0));
pylab.xlim(0, self.w)
pylab.ylim(self.l, 0)
def _cut_windows_vertically(self, door_top, roof_top, sky_sig, win_strip):
win_sig = np.percentile(win_strip, 85, axis=1)
win_sig[sky_sig > 0.5] = 0
if win_sig.max() > 0:
win_sig /= win_sig.max()
win_sig[:roof_top] = 0
win_sig[door_top:] = 0
runs, starts, values = run_length_encode(win_sig > 0.5)
win_heights = runs[values]
win_tops = starts[values]
if len(win_heights) > 0:
win_bottom = win_tops[-1] + win_heights[-1]
win_top = win_tops[0]
win_vertical_spacing = np.diff(win_tops).mean() if len(win_tops) > 1 else 0
else:
win_bottom = win_top = win_vertical_spacing = -1
self.top = int(win_top)
self.bottom = int(win_bottom)
self.vertical_spacing = int(win_vertical_spacing)
self.vertical_scores = make_list(win_sig)
self.heights = np.array(win_heights)
self.tops = np.array(win_tops)
def ransac_guess_color(colors, n_iter=50, std=2):
colors = rgb2lab(colors)
colors = colors.reshape(-1, 3)
masked = colors[:, 0] < 0.1
colors = colors[~masked]
assert len(colors) > 0, "Must have at least one color"
best_mu = np.array([0, 0, 0])
best_n = 0
for k in range(n_iter):
subset = colors[np.random.choice(np.arange(len(colors)), 1)]
mu = subset.mean(0)
#inliers = (((colors - mu) ** 2 / std) < 1).all(1)
inliers = ((np.sqrt(np.sum((colors - mu)**2, axis=1)) / std) < 1)
mu = colors[inliers].mean(0)
n = len(colors[inliers])
if n > best_n:
best_n = n
best_mu = mu
#import ipdb; ipdb.set_trace()
best_mu = np.squeeze(lab2rgb(np.array([[best_mu]])))
return best_mu
def joint_density(X, Y, bounds=None):
"""
Plots joint distribution of variables.
Inherited from method in src/graphics.py module in project
git://github.com/aflaxman/pymc-example-tfr-hdi.git
"""
if bounds:
X_min, X_max, Y_min, Y_max = bounds
else:
X_min = X.min()
X_max = X.max()
Y_min = Y.min()
Y_max = Y.max()
pylab.plot(X, Y, linestyle='none', marker='o', color='green', mec='green', alpha=.2, zorder=-99)
gkde = scipy.stats.gaussian_kde([X, Y])
x,y = pylab.mgrid[X_min:X_max:(X_max-X_min)/25.,Y_min:Y_max:(Y_max-Y_min)/25.]
z = pylab.array(gkde.evaluate([x.flatten(), y.flatten()])).reshape(x.shape)
pylab.contour(x, y, z, linewidths=2)
pylab.axis([X_min, X_max, Y_min, Y_max])
def plot_profiles(self):
"""
Plot TOPP profiles, e.g. for debugging.
"""
import pylab
pylab.ion()
self.topp.WriteProfilesList()
self.topp.WriteSwitchPointsList()
profileslist = TOPP.TOPPpy.ProfilesFromString(
self.topp.resprofilesliststring)
switchpointslist = TOPP.TOPPpy.SwitchPointsFromString(
self.topp.switchpointsliststring)
TOPP.TOPPpy.PlotProfiles(profileslist, switchpointslist)
TOPP.TOPPpy.PlotAlphaBeta(self.topp)
pylab.title("%s phase profile" % type(self).__name__)
pylab.axis([0, 1, 0, 10])
def drop_variable_before_preparation(self, df):
# Acceptable limit of NaN in features
limit_of_nans = 0.3*df.shape[0]
# limit_of_nans = 800
for feature in self.features_with_missing_values_in_dataframe(df).index:
if df[feature].isnull().sum() > limit_of_nans:
df = df.drop([feature], axis=1)
# df = df.drop(['Alley'], axis=1)
# df = df.drop(['MasVnrType'], axis=1)
# df = df.drop(["Utilities", "LotFrontage", "Alley", "MasVnrType", "MasVnrArea", "BsmtQual",
# "BsmtCond", "BsmtExposure", "BsmtFinType1", "BsmtFinType2",
# "Electrical", "FireplaceQu", "GarageType", "GarageYrBlt",
# "GarageFinish", "GarageQual", "GarageCond", "PoolQC",
# "Fence", "MiscFeature"], axis=1)
return df
def drop_variable(self, df):
# if HousePrices._is_one_hot_encoder:
# Drop all categorical feature helping columns ('Num')
# Todo: is it defined when importing data set? _feature_names_num
# for feature_name in HousePrices._feature_names_num:
# df = df.drop([feature_name], axis=1)
# is_with_feature_agglomeration = 0
# if is_with_feature_agglomeration:
# print(df.shape)
# df = HousePrices.feature_agglomeration(df)
# print(df.shape)
# df = df.drop(['Fireplaces'], axis=1)
df = df.drop(['Id'], axis=1)
if not any(tuple(df.columns == 'SalePrice')):
# All feature var names occuring in test data is assigned the public varaible df_test_all_feature_var_names.
self.df_test_all_feature_var_names = df.columns
return df
def outlier_identification(self, model, x_train, y_train):
# Split the training data into an extra set of test
x_train_split, x_test_split, y_train_split, y_test_split = train_test_split(x_train, y_train)
print('\nOutlier shapes')
print(np.shape(x_train_split), np.shape(x_test_split), np.shape(y_train_split), np.shape(y_test_split))
model.fit(x_train_split, y_train_split)
y_predicted = model.predict(x_test_split)
residuals = np.absolute(y_predicted - y_test_split)
rmse_pred_vs_actual = self.rmse(y_predicted, y_test_split)
outliers_mask = residuals >= rmse_pred_vs_actual
# outliers_mask = np.insert(np.zeros((np.shape(y_train_split)[0],), dtype=np.int), np.shape(y_train_split)[0],
# outliers_mask)
outliers_mask = np.concatenate([np.zeros((np.shape(y_train_split)[0],), dtype=bool), outliers_mask])
not_an_outlier = outliers_mask == 0
# Resample the training set from split, since the set was randomly split
x_out = np.insert(x_train_split, np.shape(x_train_split)[0], x_test_split, axis=0)
y_out = np.insert(y_train_split, np.shape(y_train_split)[0], y_test_split, axis=0)
return x_out[not_an_outlier, ], y_out[not_an_outlier, ]
def tile_images(image_batch, image_width=28, image_height=28, image_channel=1, dir=None, filename="images"):
if dir is None:
raise Exception()
try:
os.mkdir(dir)
except:
pass
fig = pylab.gcf()
fig.set_size_inches(16.0, 16.0)
pylab.clf()
pylab.gray()
for m in range(100):
pylab.subplot(10, 10, m + 1)
pylab.imshow(image_batch[m].reshape((image_width, image_height)), interpolation="none")
pylab.axis("off")
pylab.savefig("{}/{}.png".format(dir, filename))
def view_(_pred,_lable):
fname = ['Captcha/lv3/%i.jpg' %i for i in range(20)]
img = []
for fn in fname:
img.append(Image.open(open(fn)))
#img.append(misc.imread(fn).astype(np.float))
for i in range(len(img)):
pylab.subplot(4,5,i+1); pylab.axis('off')
pylab.imshow(img[i])
#pylab.imshow( np.dot(np.array(img[i])[...,:3],[0.299,0.587,0.114]) , cmap=plt.get_cmap("gray"))
#pylab.text(40,60,_pred[i],color = 'b')
if ( _pred[i] == _lable[i] ):
pylab.text(40,65,_pred[i],color = 'b',size = 15)
else:
pylab.text(40,65,_pred[i],color = 'r',size = 15)
pylab.text(40,92,_lable[i],color = 'g',size = 15)
pylab.show()
def visualize_reconstruction(xp, model, x, visualization_dir, epoch, gpu=False):
x_variable = chainer.Variable(xp.asarray(x))
_x = model.decode(model.encode(x_variable), test=True)
_x.to_cpu()
_x = _x.data
fig = pylab.gcf()
fig.set_size_inches(8.0, 8.0)
pylab.clf()
pylab.gray()
for m in range(50):
i = m / 10
j = m % 10
pylab.subplot(10, 10, 20 * i + j + 1, xticks=[], yticks=[])
pylab.imshow(x[m].reshape((28, 28)), interpolation="none")
pylab.subplot(10, 10, 20 * i + j + 10 + 1, xticks=[], yticks=[])
pylab.imshow(_x[m].reshape((28, 28)), interpolation="none")
# pylab.imshow(np.clip((_x_batch.data[m] + 1.0) / 2.0, 0.0, 1.0).reshape(
# (config.img_channel, config.img_width, config.img_width)), interpolation="none")
pylab.axis("off")
pylab.savefig("{}/reconstruction_{}.png".format(visualization_dir, epoch))
# pylab.show()
def tile_binary_images(x, dir=None, filename="x", row=10, col=10):
if dir is None:
raise Exception()
try:
os.mkdir(dir)
except:
pass
fig = pylab.gcf()
fig.set_size_inches(col * 2, row * 2)
pylab.clf()
pylab.gray()
for m in range(row * col):
pylab.subplot(row, col, m + 1)
pylab.imshow(np.clip(x[m], 0, 1), interpolation="none")
pylab.axis("off")
pylab.savefig("{}/{}.png".format(dir, filename))
def get_sqe_above(self,high_p,rich_return=False):
p = dict()
p['g_exc'] = high_p[0] # nS
p['sen2dec_exc'] = high_p[1] # pA/Hz
if len(high_p)>2:
p['frac_proj'] = high_p[2]
else:
p['frac_proj'] = 0.1
win1_all = np.zeros((6,6))
for i_m in xrange(len(self.m_plot)):
for i_c in xrange(len(self.c_plot)):
m = self.m_plot[i_m]
c = self.c_plot[i_c]
win1_all[i_m,i_c] = self.quick_Newsome_model(p,m,c)
sqe = 0
sqe += sum((self.p_m_m-win1_all.mean(axis=1))**2)
sqe += sum((self.p_m_c-win1_all.mean(axis=0))**2)
if rich_return:
return p
else:
return sqe
def transform_to_2d(data, max_axis):
"""
Projects 3d data cube along one axis using maximum intensity with
preservation of the signs. Adapted from nilearn.
"""
import numpy as np
# get the shape of the array we are projecting to
new_shape = list(data.shape)
del new_shape[max_axis]
# generate a 3D indexing array that points to max abs value in the
# current projection
a1, a2 = np.indices(new_shape)
inds = [a1, a2]
inds.insert(max_axis, np.abs(data).argmax(axis=max_axis))
# take the values where the absolute value of the projection
# is the highest
maximum_intensity_data = data[inds]
return np.rot90(maximum_intensity_data)
def tile_binary_images(x, dir=None, filename="x", row=10, col=10):
if dir is None:
raise Exception()
try:
os.mkdir(dir)
except:
pass
fig = pylab.gcf()
fig.set_size_inches(col * 2, row * 2)
pylab.clf()
pylab.gray()
for m in range(row * col):
pylab.subplot(row, col, m + 1)
pylab.imshow(np.clip(x[m], 0, 1), interpolation="none")
pylab.axis("off")
pylab.savefig("{}/{}.png".format(dir, filename))
def tile_binary_images(x, dir=None, filename="x"):
if dir is None:
raise Exception()
try:
os.mkdir(dir)
except:
pass
fig = pylab.gcf()
fig.set_size_inches(16.0, 16.0)
pylab.clf()
pylab.gray()
for m in range(100):
pylab.subplot(10, 10, m + 1)
pylab.imshow(np.clip(x[m], 0, 1), interpolation="none")
pylab.axis("off")
pylab.savefig("{}/{}.png".format(dir, filename))
def plot_signals(input_data, filename=None,downsamplefactor=1,n_columns=1):
import pylab as pl
n_rows = input_data.signal.n_channels()
n_rows = int(n_rows/n_columns)
print str(n_rows) + ' ' + str(n_columns)
for row in range(n_rows):
for col in range(n_columns):
print (row)*n_columns+col+1
pl.subplot(n_rows, n_columns, row*n_columns+col+1)
if downsamplefactor==1:
pl.plot(input_data.timebase, input_data.signal.get_channel(row*n_columns+col))
pl.axis([-0.01,0.1,-5, 5])
else:
plotdata=input_data.signal.get_channel(row*n_columns+col)
timedata=input_data.timebase
pl.plot(timedata[0:len(timedata):downsamplefactor], plotdata[0:len(timedata):downsamplefactor])
pl.axis([-0.01,0.1,-5,5])
if filename != None:
pl.savefig(filename)
else:
pl.show()
def visualize_x(reconstructed_x_batch, image_width=28, image_height=28, image_channel=1, dir=None):
if dir is None:
raise Exception()
try:
os.mkdir(dir)
except:
pass
fig = pylab.gcf()
fig.set_size_inches(16.0, 16.0)
pylab.clf()
if image_channel == 1:
pylab.gray()
for m in range(100):
pylab.subplot(10, 10, m + 1)
if image_channel == 1:
pylab.imshow(reconstructed_x_batch[m].reshape((image_width, image_height)), interpolation="none")
elif image_channel == 3:
pylab.imshow(reconstructed_x_batch[m].reshape((image_channel, image_width, image_height)), interpolation="none")
pylab.axis("off")
pylab.savefig("%s/reconstructed_x.png" % dir)
def removeIllumination2(self, size, title = ''):
out = ndimage.filters.gaussian_filter(self.image, size)
pylab.figure()
pylab.subplot(2,2,1)
pylab.axis('off')
pylab.imshow(self.image)
pylab.subplot(2,2,2)
pylab.axis('off')
pylab.imshow(out)
pylab.subplot(2,2,3)
pylab.axis('off')
pylab.imshow(self.image - out)
pylab.subplot(2,2,4)
pylab.axis('off')
pylab.imshow(self.smooth - out)
if title != '':
pylab.savefig(title)
pylab.close()
else:
pylab.show()
self.smooth -= out
return self.image - out
def draw2D(self, title, image=[]):
pylab.figure()
if image == []:
pylab.imshow(self.image, 'gray')
else:
pylab.imshow(image, 'gray')
pylab.axis('off')
pylab.autoscale(False)
for i in xrange(self.nComponents):
xeq = lambda t: self.params[6 * i + 3] * np.cos(t) * np.cos(self.params[6 * i + 5]) + self.params[
6 * i + 4] * np.sin(
t) * np.sin(self.params[6 * i + 5]) + self.params[6 * i + 1]
yeq = lambda t: - self.params[6 * i + 3] * np.cos(t) * np.sin(self.params[6 * i + 5]) + self.params[
6 * i + 4] * np.sin(
t) * np.cos(self.params[6 * i + 5]) + self.params[6 * i + 2]
t = np.linspace(0, 2 * np.pi, 100)
x = xeq(t)
y = yeq(t)
pylab.scatter(self.params[6 * i + 2], self.params[6 * i + 1], color='k')
pylab.plot(y.astype(int), x.astype(int), self.colors[i] + '-')
pylab.savefig(title)
pylab.close()
def toBin(img, thr=200):
#return (img < thr).astype(np.uint8)
return (img < thr).max(axis=2).astype(np.uint8)
def GetLineSegments(itrim):
"""
Segment an image in lines and interline spaces
Returns lists of both (position width)
"""
# sum along pixel lines
asum = np.sum(itrim, axis=1)
abin = asum > 0
sp = []
tx = []
lastval=-1
lastpos=-1
for i in range(0, abin.size):
if abin[i] != lastval:
lastval = abin[i]
if lastval:
tx.append(np.array((i,0)))
if i>0:
sp[-1][1] = i-sp[-1][0]
else:
sp.append(np.array((i,0)))
if i>0:
tx[-1][1] = i-tx[-1][0]
# set the last segment lenght
if tx[-1][1] == 0: tx[-1][1] = itrim.shape[0] - tx[-1][0]
if sp==[]:# empy if there is just one line in the image
sp.append(np.array((0,0)))
else:
if sp[-1][1] == 0: sp[-1][1] = itrim.shape[0] - sp[-1][0]
return tx, sp
def align(l1, l2, axis):
if axis == 1: #horizontal alignment, we do not care about the right line end
#cw = min(l2.shape[1],l1.shape[1])
#l1 = l1[:,:cw]
#l2 = l2[:,:cw]
#compute correlation
sc1 = np.sum(l1, axis=1-axis)
sc2 = np.sum(l2, axis=1-axis)
cor = np.correlate(sc1,sc2,"same")
posErr = np.argmax(cor)-sc1.shape[0]/2
#place at right position
if posErr > 0:
l2c = l2.copy()
l2c[:]=0
l2c[:,posErr:] = l2[:,:-posErr]
l2 = l2c
elif posErr < 0:
l1c = l1.copy()
l1c[:]=0
l1c[:,-posErr:] = l1[:,:posErr]
l1=l1c
else: #vertical alignment, we cate about both ends
#compute correlation
sc1 = np.sum(l1, axis=1-axis)
sc2 = np.sum(l2, axis=1-axis)
cor = np.correlate(sc1,sc2,"same")
posErr = np.argmax(cor)-sc1.shape[0]/2
#place at right position
if posErr > 0:
l2c=l2.copy()
l2c[:]=0
l2c[posErr:,:] = l2[:-posErr,:]
l2 = l2c
elif posErr < 0:
l1c=l1.copy()
l1c[:]=0
l1c[-posErr:,:]=l1[:posErr,:]
l1 = l1c
return posErr, l1, l2
def edgeplot(self, TT, ps):
for ei,X in enumerate(self.edges):
(i, j) = X[:2]
Ta = TT[i]
Tb = TT[j]
plt.clf()
if len(Ta) > 1000:
nbins = 101
ra = np.hstack((Ta.ra, Tb.ra))
dec = np.hstack((Ta.dec, Tb.dec))
H,xe,ye = np.histogram2d(ra, dec, bins=nbins)
(matchRA, matchDec, dr,dd) = self.edge_matches(ei, goodonly=True)
G,xe,ye = np.histogram2d(matchRA, matchDec, bins=(xe,ye))
assert(G.shape == H.shape)
img = antigray(H / H.max())
img[G>0,:] = matplotlib.cm.hot(G[G>0] / H[G>0])
ax = setRadecAxes(xe[0], xe[-1], ye[0], ye[-1])
plt.imshow(img, extent=(min(xe), max(xe), min(ye), max(ye)),
aspect='auto', origin='lower', interpolation='nearest')
plt.axis(ax)
else:
self.plotallstars([Ta,Tb])
self.plotmatchedstars(ei)
plt.xlabel('RA (deg)')
plt.ylabel('Dec (deg)')
ps.savefig()
# one plot per edge
def hsvoffsets(self, TT, rad, apply=False):
print 'hsv offsets plot'
plt.clf()
for ix,X in enumerate(self.edges):
X = self.get_edge_dradec_arcsec(ix, corrected=apply, goodonly=True)
(matchRA, matchDec, dra, ddec) = X
print 'matchRA,Dec:', len(matchRA), len(matchDec)
print 'dra,dec:', len(dra), len(ddec)
for ra,dec,dr,dd in zip(matchRA, matchDec, dra, ddec):
angle = arctan2(dd, dr) / (2.*pi)
angle = fmod(angle + 1, 1.)
mag = hypot(dd, dr)
mag = min(1, mag/(0.5*rad))
rgb = colorsys.hsv_to_rgb(angle, mag, 0.5)
plt.plot([ra], [dec], '.', color=rgb, alpha=0.5)
# legend in top-right corner.
ax=plt.axis()
xlo,xhi = plt.gca().get_xlim()
ylo,yhi = plt.gca().get_ylim()
# fraction
keycx = xlo + 0.90 * (xhi-xlo)
keycy = ylo + 0.90 * (yhi-ylo)
keyrx = 0.1 * (xhi-xlo) / 1.4 # HACK
keyry = 0.1 * (yhi-ylo)
nrings = 5
for i,(rx,ry) in enumerate(zip(np.linspace(0, keyrx, nrings), np.linspace(0, keyry, nrings))):
nspokes = ceil(i / float(nrings-1) * 30)
angles = np.linspace(0, 2.*pi, nspokes, endpoint=False)
for a in angles:
rgb = colorsys.hsv_to_rgb(a/(2.*pi), float(i)/(nrings-1), 0.5)
plt.plot([keycx + rx*sin(a)], [keycy + ry*cos(a)], '.', color=rgb, alpha=1.)
plt.axis(ax)
plt.xlabel('RA (deg)')
plt.ylabel('Dec (deg)')