Change units of matplotlib subplot (RA hh:mm to degrees) - matplotlib

I am trying to plot an image with axes in RA and DEC. I cannot figure out how to change units from h:m:s to deg for my RA axis. I tried the following 2 methods and my output axes were the same (ticks: 5h 42m 15s, 00, 41m 45s, ...)
filename = get_pkg_data_filename('flame.fits')
hdu = fits.open(filename)[0]
wcs = WCS(hdu.header)
fig = plt.figure()
fig.add_subplot(111, projection=wcs)
plt.imshow(hdu.data, origin='lower', cmap=plt.cm.viridis)
plt.xlabel('RA')
plt.ylabel('Dec')
plt.show()
METHOD 2:
flame = fits.getdata('flame.fits')
hdr = fits.getheader('flame.fits')
wcs = WCS(hdr)
ax = plt.subplot(projection=wcs)
plt.imshow(flame, origin='lower')
plt.xlabel('RA')
plt.ylabel('Dec')
plt.show()
How do I change the X-axis (RA) to degrees?
Thanks!
P.S.:
This
ax = fig.gca()
ra = ax.coords[0]
dec = ax.coords[1]
ra.set_format_unit('ra')
dec.set_format_unit('dec')
result in AttributeError: 'AxesSubplot' object has no attribute 'coords'

Related

Matplotlib doesn't show both datasets points on the figure when I want to create scatter plot with

I'm sure that I've done all things right but in the end the result I got is a sccatter plot that only shows the second datasets data.
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.scatter(train["ENGINESIZE"], train["CO2EMISSIONS"], color = "green")
ax1.scatter(test["ENGINESIZE"], test["CO2EMISSIONS"], color = "red")
plt.xlabel("Engine Size")
plt.ylabel("Emission")
plt.show()
Here You can see what's going on in my output in link below.
It shows only red data(test data) in the output.
Where is the "output link below", please? For now I can only imagine what you are describing.
Also it helps if both plots have the same axis. That is, both have the same x-axis and then they can vary on their y-axis.
If so:
fig, ax = plt.subplots()
df.plot(kind = 'scatter', x= train["ENGINESIZE"], y = train["CO2EMISSIONS"], color = {'g'}, ax = ax)
df.plot(kind = 'scatter', x= test["ENGINESIZE"], y = test["CO2EMISSIONS"], color = {'r'}, ax = ax)
plt.xlabel()

python plot multiple bar ranges with dates

I have this two dataframe:
x1=[{"dates":'2018-01-31',"rev":-2},
{"dates":'2018-02-28',"rev":-5},
{"dates":'2018-03-31',"rev":-7},
{"dates":'2018-04-30',"rev":-8},
{"dates":'2018-05-31',"rev":-9},
{"dates":'2018-06-30',"rev":-2},
{"dates":'2018-07-31',"rev":1},
{"dates":'2018-08-31',"rev":2},
{"dates":'2018-09-30',"rev":3},
{"dates":'2018-10-31',"rev":4},
{"dates":'2018-11-30',"rev":4},
{"dates":'2018-12-31',"rev":5}]
x2=[{"dates":'2018-01-31',"rev":-5},
{"dates":'2018-02-28',"rev":-9},
{"dates":'2018-03-31',"rev":-9},
{"dates":'2018-04-30',"rev":-6},
{"dates":'2018-05-31',"rev":-1},
{"dates":'2018-06-30',"rev":-2},
{"dates":'2018-07-31',"rev":-14},
{"dates":'2018-08-31',"rev":2},
{"dates":'2018-09-30',"rev":3},
{"dates":'2018-10-31',"rev":4},
{"dates":'2018-11-30',"rev":-4},
{"dates":'2018-12-31',"rev":5}]
df1=pd.DataFrame(x1)
df1["dates"]=pd.to_datetime(df1.dates)
df2=pd.DataFrame(x2)
df2["dates"]=pd.to_datetime(df2.dates)
(Thanks Flavio Moraes
)
I would like to plot then as a bar plot. The matplotlib guide suggests to do something like the following:
width = 0.35
fig, ax = plt.subplots()
rects1 = ax.bar(x - width/2, y1, width, label='y1')
rects2 = ax.bar(x + width/2, y2, width, label='y2')
However, this seems to not working with dates. Indeed I have tried:
ax = plt.axes()
widthb = 10
rects1 = ax.bar(df1.dates - widthb/2, df1.rev,color='blue', width=widthb)
rects2 = ax.bar(df2.dates + widthb/2, df2.rev,color='red', width=widthb)
ax.xaxis_date()
As expected, I get the following error:
unsupported operand type(s) for -: 'DatetimeIndex' and 'float'
Do you have any suggestion to overcome this problem and simultaneously to have a beautiful plot?
Thanks
Let's try merge and plot:
ax = df1.merge(df2, on='dates', how='outer').plot.bar(x='dates')
# other format with `ax`
ax.xaxis_date()
Output:

Plot streamlines on a matplotlib contourf plot

I have a matplotlib contourf plot of longitudes and pressure levels in the vertical. I am trying to plot streamlines on this using the plt.streamplot function in matplotlib and using U and V wind data.
If I plot only the streamplot, it works fine. But I cannot get the streamlines to overlay on the contour plot.
Here is my code:-
fig, axes = plt.subplots(nrows, ncols, sharex=True, sharey=True)
if (nrows==1 and ncols==1):
axes=[axes]
else:
axes=axes.flat
for i, ax in enumerate(axes):
X,Y = np.meshgrid(x[i],y[i])
levels=np.arange(vmin,vmax,step)
h = ax.contourf(X,Y,z[i],cmap=cmap,levels=levels,extend='both')
w = ax.streamplot(X, Y, W[i], Z[i], linewidth=0.2, color='gray')
And this is the plot I get:
The following is the streamline plot, not sure why the y axis is from 0-120 instead of 0 to 1000:
You use curvilinear coordinate system for contour plot (lat-p).
You have to convert u,v to coordinate system of contour something like here (this is example for lat-lon you have to modify it to use pressure levels):
def myStreamPlot(lon,lat,u,v,color='k',density=2.5):
from scipy.interpolate import griddata
n,m = u.shape[1],u.shape[0]
x = np.linspace(np.nanmin(lon), np.nanmax(lon), n)
y = np.linspace(np.nanmin(lat), np.nanmax(lat), m)
xi, yi = np.meshgrid(x,y)
lon = lon.ravel()
lat = lat.ravel()
u = u.ravel()
v = v.ravel()
gu = griddata(zip(lon,lat), u, (xi,yi))
gv = griddata(zip(lon,lat), v, (xi,yi))
gspd = np.sqrt(gu**2 + gv**2)
SL = plt.streamplot(x,y,gu,gv,linewidth=1.,color=color,density=density)
This code use griddata function of scipy.interpolate: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.griddata.html

Matplotlib add_subplot does not add to the expected position

fig = plt.figure(figsize=(10,30))
ax1 = fig.add_subplot(1,1,1)
ax2 = fig.add_subplot(2,1,2)
ax3 = fig.add_subplot(3,1,3)
ax1.imshow(np.ones((100,200,3))) # white
ax2.imshow(np.zeros((100,200,3))) # black
ax3.imshow(np.zeros((100,200,3))) # black
The above code yields the below image
ax1 the white image is where I expected to be. the ax2, ax3, the black images are overlapped with each other
Figured it out!
Turns out add_subplot requires the overal dimensions. So the correct way to write it this
fig = plt.figure(figsize=(10,15))
ax1 = fig.add_subplot(3,1,1)
ax2 = fig.add_subplot(3,1,2)
ax3 = fig.add_subplot(3,1,3)

How to remove spacing from figure created with imshow()?

I have a matrix that I want to show (np.asarray(vectors).T) and so far everything works except that the image is having way to much padding below the bottom x-axis.
I tried to use tight_layout() but it has absolutely no effect.
How can I crop my image correctly such that there is not so much spacing
import numpy as np
import matplotlib.pyplot as plt
# Creating fake data
topn = 15
nb_classes = 13
rows = 27
columns = nb_classes * topn
labels = ['Class {:d}'.format(i) for i in range(nb_classes)]
m = np.random.random((rows,columns))
# Plotting
plt.figure()
plt.imshow(m, interpolation='none')
plt.grid(False)
plt.xlabel('Word', size=16)
plt.ylabel('Dimension', size=16)
ax = plt.gca()
ax.yaxis.set_ticks_position("right")
ax.xaxis.set_ticks_position("top")
yticks = list()
for i in range(0, nb_classes):
if i != 0:
plt.axvline(i*n - 0.5, c='w')
yticks.append((i*n - 0.5 + n/2))
plt.xticks(yticks, labels, rotation=90)
plt.tight_layout()
plt.show()
This is the resulting image (grey lines just to visualize the size):
Use plt.figure(figsize=(8,4)) and aspect='auto' in the call of plt.imshow:
import numpy as np
import matplotlib.pyplot as plt
# Creating fake data
topn = 15
nb_classes = 13
rows = 27
columns = nb_classes * topn
labels = ['Class {:d}'.format(i) for i in range(nb_classes)]
m = np.random.random((rows,columns))
# Plotting
plt.figure(figsize=(8,4))
plt.imshow(m, interpolation='None', aspect='auto')
plt.grid(False)
plt.xlabel('Word', size=16)
plt.ylabel('Dimension', size=16)
ax = plt.gca()
ax.yaxis.set_ticks_position("right")
ax.xaxis.set_ticks_position("top")
yticks = list()
for i in range(0, nb_classes):
if i != 0:
plt.axvline(i*n - 0.5, c='w')
yticks.append((i*n - 0.5 + n/2))
plt.xticks(yticks, labels, rotation=90)
plt.tight_layout()
plt.show()