Problems with gridspec plotting with APLpy - python

So I'm attempting to plot to fits images (identical fits images) with some annotations provided by a DS9 region file using APLpy:
My script is as follows:
import aplpy
import matplotlib
import matplotlib.pyplot as pyplot
import matplotlib.gridspec as gridspec
from astropy.io import fits
matplotlib.rc('xtick', labelsize=8)
matplotlib.rc('ytick', labelsize=8)
#matplotlib.rc('text', usetex=True)
#matplotlib.rcParams['xtick.direction'] = 'out'
#matplotlib.rcParams['ytick.direction'] = 'out'
matplotlib.rcParams['grid.alpha'] = 0.3
nullfmt = pyplot.NullFormatter()
fig = pyplot.figure(figsize=(26,12))
gridspec_layout = gridspec.GridSpec(1,2)
#gridspec_layout.update(hspace=0.0, wspace=0.005)
M33_galax = aplpy.FITSFigure('/Users/.../SDSS_g_c_rescale.fits', figure=fig, subplot=list(gridspec_layout[0].get_position(fig).bounds), dimensions=[0, 1], slices=[0])
M33_stars = aplpy.FITSFigure('/Users/.../SDSS_g_c_rescale.fits', figure=fig, subplot=list(gridspec_layout[1].get_position(fig).bounds), dimensions=[0, 1], slices=[0])
#dimensions=[0, 1], slices=[1]
M33_galax.show_regions('SDSS_galaxy_match.reg')
#M33_stars.show_regions('')
M33_galax.set_tick_labels_format(xformat='hh:mm:ss.ss',yformat='dd:mm:ss')
M33_galax.set_tick_labels_font(size='x-small')
M33_galax.axis_labels.set_ytext(r'$\delta\,,\mathrm{Dec}\,\mathrm{(J2000)}$')
M33_galax.axis_labels.set_xtext(r'$\alpha\,,\mathrm{RA}\,\mathrm{(J2000)}$')
M33_galax.axis_labels.set_font(size='small')
M33_galax.axis_labels.set_ypad(10)
M33_galax.axis_labels.set_xpad(10)
M33_galax.add_grid()
M33_galax.grid.set_alpha(0.1)
M33_stars.set_tick_labels_format(xformat='hh:mm:ss.ss',yformat='dd:mm:ss')
M33_stars.set_tick_labels_font(size='x-small')
M33_stars.axis_labels.set_ytext(r'$\delta\,,\mathrm{Dec}\,\mathrm{(J2000)}$')
M33_stars.axis_labels.set_xtext(r'$\alpha\,,\mathrm{RA}\,\mathrm{(J2000)}$')
M33_stars.axis_labels.set_font(size='small')
M33_stars.axis_labels.set_ypad(10)
M33_stars.axis_labels.set_xpad(10)
M33_stars.add_grid()
M33_stars.grid.set_alpha(0.1)
pyplot.show()
However, I am finding the following is the output:
Would anyone know where I am going wrong with this?

You need to use show_grayscale or show_colorscale to display the images, e.g.:
M33_galax.show_grayscale()

Related

How to display audio at the right side of matplotlib

The following code display the image and audio in the top-bottom style:
Here is the test code:
import librosa
import matplotlib.pyplot as plt
import IPython.display as ipd
def plot_it(name, audio, sample_rate):
plt.figure(figsize=(8, 1))
plt.plot(audio)
plt.gca().set_title(name)
plt.show()
ipd.display(ipd.Audio(data=audio, rate=sample_rate))
Is it possible for changing the "top-bottom" style to "left-right" style for displaying the audio at the right side of the plt figure?
You can use a GridspecLayout which is similar to matplotlib's GridSpec. In order to direct to output into the needed grid cells, you can capture it using the Output widget:
import librosa
import matplotlib.pyplot as plt
import IPython.display as ipd
from ipywidgets import Output, GridspecLayout
def plot_it(name, audio, sample_rate):
grid = GridspecLayout(1, 2, align_items='center')
out = Output()
with out:
fig, ax = plt.subplots(figsize=(8, 1))
ax.plot(audio)
ax.set_title(name)
plt.close(fig)
ipd.display(ax.figure)
grid[0, 0] = out
out = Output()
with out:
ipd.display(ipd.Audio(data=audio, rate=sample_rate))
grid[0, 1] = out
ipd.display(grid)
name = 'nutcracker'
filename = librosa.example(name)
y, sr = librosa.load(filename)
plot_it(name, y, sr)
(It is essential to close the figure, otherwise you'll have double output of the figure. This is easier to do this using the OOP than the pyplot interface, that's why I changed your matplotlib code a bit)

How to save plt image to local in python

I'm trying to save my plotted image to local, I've tried to follow some tutorials from the internet, but still can't, can anyone help me?
import pandas as pd
import matplotlib.pyplot as plt
joined_data = pd.read_csv('/content/drive/MyDrive/Kurs/clean_data/forecast.csv')
# First plot
f, (ax1, ax2) = plt.subplots(1, 2, figsize=(20,8))
ax1.plot(joined_data["kurs_jual"])
ax1.set_xlabel("Tanggal", fontsize=12)
ax1.set_ylabel("Kurs Jual")
ax1.set_title("Kurs Jual VND")
# second plot
ax2.plot(joined_data["kurs_beli"], color="orange")
ax2.set_xlabel("Tanggal", fontsize=12)
ax2.set_ylabel("Kurs Beli")
ax2.set_title("Kurs Beli VND")
plt.show()
plt.savefig('/content/drive/MyDrive/Kurs/clean_data/forecast_vnd.png')
Use plt.savefig('/content/drive/MyDrive/Kurs/clean_data/forecast_vnd.png') before plt.show() else the saved picture would be blank.

sns matplotlib output slicing the saved image [duplicate]

This question already has answers here:
Plt.show shows full graph but savefig is cropping the image
(3 answers)
Closed 1 year ago.
I am trying to save sns matplotlib output as jpg file and reopen it with cv2.
but i am facing distinct data loss, would someone help me to resolve, i tried in several savefig options and documentations.
sample code
import pandas as pd
import numpy as np
import cv2
import seaborn as sns
import matplotlib.pyplot as plt
by_c = None
fig = plt.Figure(figsize=(5, 4), dpi=100)
g = sns.FacetGrid(pd.DataFrame(np.random.random(10)*150, columns=['col']), col=None, row=None, height=3.5, aspect=1)
g.map_dataframe(sns.histplot, x='col')
plt.title('col'+' - '+str(by_c)+'-', fontsize=12)
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.savefig('temp.png')
plt.show()
Out:
Saved picture example of 'temp.png'
out:
reopening image
im = cv2.imread('temp.png')
plt.imshow(im)
Out1:
Image title and lables sliced bit, i am not sure how else i can save it. Would someone please help to resolve it
To set the quality of the image use the dpi, and also specify the bbox_inches for a full layout. If not, it will consider the nearest view of the image
import pandas as pd
import numpy as np
import cv2
import seaborn as sns
import matplotlib.pyplot as plt
by_c = None
fig = plt.Figure(figsize=(5, 4), dpi=100)
g = sns.FacetGrid(pd.DataFrame(np.random.random(10)*150, columns=['col']), col=None, row=None, height=3.5, aspect=1)
g.map_dataframe(sns.histplot, x='col')
plt.title('col'+' - '+str(by_c)+'-', fontsize=12)
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.savefig('temp.png',dpi=300, bbox_inches = "tight")
#plt.savefig('temp.png')
plt.show()
im = cv2.imread('temp.png')
plt.imshow(im)
Resultant Image:

Matplotlib inline in Jupyter - how to contol when the plot is shown?

I have a function that creates a figure and for some reason it is shown in Jupyter notebook twice, even though I didn't run show at all. I pass the fig and ax as an output of this function, and plan to show it only later.
I get confused between plt, fig and ax functionaries and guess that the answer is hidden somewhere there.
Here is an anonymised version of my code:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib inline
def plot_curve(dummydata):
# builds a chart
fig,ax = plt.subplots(1) # get subplots
fig.set_figheight(7)
fig.set_figwidth(12) #set shape
plt.plot(dummydata.x1, dummydata.y1,label = 'l1') #curve 1
plt.plot(dummydata.x2, dummydata.y2,label = 'l2') #curve2
plt.xlabel('xlabel') #labels
plt.ylabel('xlabel')
plt.yscale('linear') #scale and bounds
plt.ylim(0,100)
ymin,ymax= ax.get_ylim()
ax.axhline(1, color='k', linestyle=':', label = 'lab1') #guideline - horizontal
ax.axvline(2, color='r',linestyle='--', label = 'lab2') #guideline - vertical
ax.axvline(3, color='g',linestyle='--', label = 'lab3') #guideline - vertical
ax.arrow(1,2,3,0, head_width=0.1, head_length=0.01, fc='k', ec='k') # arrow
rect = mpl.patches.Rectangle((1,2), 2,3, alpha = 0.1, facecolor='yellow',
linewidth=0 , label= 'lab4') #yellow area patch
ax.add_patch(rect)
plt.legend()
plt.title('title')
return fig,ax
and then call it with:
for i in range(3):
dummydata = pd.DataFrame({
'x1':np.arange(1+i,100,0.1),
'y1':np.arange(11+i,110,0.1),
'x2':np.arange(1+i,100,0.1),
'y2':np.arange(21+i,120,0.1)
})
fig,ax = plot_curve(dummydata) #get the chart
What should I change to not show the figure by default, and show it only by my command?
Thanks
Try disabling matplotlib interactive mode using plt.ioff(). With interactive mode disabled the plots will only be shown with an explicit plt.show().
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib inline
# Desactivate interactive mode
plt.ioff()
def plot_curve(dummydata):
# the same code as before
Then in another cell
for i in range(3):
dummydata = pd.DataFrame({
'x1':np.arange(1+i,100,0.1),
'y1':np.arange(11+i,110,0.1),
'x2':np.arange(1+i,100,0.1),
'y2':np.arange(21+i,120,0.1)
})
# I'am assuming this should not be in the for loop
# The plot will NOT be shown because we are not in interactive mode
fig, ax = plot_curve(dummydata) #get the chart
No plot will be shown yet.
Now in another cell
# Now ANY plot (figure) which was created and not shown yet will be finally shown
plt.show()
The plot is finally shown. Note that if you have created several plots all of them will be shown now.
Try this:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib
With this importing you should not see the figure after plotting.
But you can see the figure by writing fig to IPython cell:
dummydata = pd.DataFrame({
'x1':np.arange(1,100,0.1),
'y1':np.arange(11,110,0.1),
'x2':np.arange(1,100,0.1),
'y2':np.arange(21,120,0.1)
})
fig,ax = plot_curve(dummydata) #get the chart
fig # Will now plot the figure.
Is this the desired output?

Colorbar ticks formatting does not work

I have the following code which produces a scatter plot with a colorbar:
#!/usr/bin/env python3
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
from matplotlib.ticker import *
import matplotlib.ticker as ticker
import matplotlib as mpl
import matplotlib.gridspec as gridspec
from list2nparr import list2nparr
# this part changes the fonts for latex handling
plt.rcParams['text.latex.preamble']=[r"\usepackage{lmodern}"]
plt.rcParams['text.usetex'] = True
plt.rcParams['font.family'] = 'lmodern'
plt.rcParams['font.size'] = 16
#==================================================================
fig,ax1 = plt.subplots()
data = list2nparr('radiant.txt')
lm = data[:,14]
bet = data[:,15]
b = data[:,18]
#
cm = plt.cm.get_cmap('jet')
sc2 = ax1.scatter(lm, bet, c=b, s=10, cmap=cm, edgecolor='none',rasterized=True)
# ==========================COLORBAR SPECS=========================
cb3 = fig.colorbar(sc2,ax = ax1, aspect=10)
cb3.ax.tick_params(labelsize=16)
cb3.set_label(r'$\beta = F_R/F_G$',size=18,labelpad=20)
cb3.formatter.set_powerlimits((0, 0))
cb3.ax.yaxis.set_major_locator(MaxNLocator(5,prune='upper')) # WHY DOES THIS LINE NOT WORK?
cb3.update_ticks()
# =======================SCATTER PLOT SPECS========================
ax1.set_ylabel('$b$, (deg)',fontsize=18,labelpad=0.5)
ax1.set_xlabel("$\lambda-\lambda_{\odot}$, (deg)",fontsize=18)
plt.savefig('test.eps', format='eps')
At some point, I am trying to format the ticks of the colorbar, requesting only five ticks while removing the uppermost label. This is illustrated in line 30, where it says: cb3.ax.yaxis.set_major_locator(MaxNLocator(5,prune='upper'))
However, this line seems to have no effect on the plot at all?
Any ideas what might be the reason for that?
EDIT
Use the locator when you create the colorbar:
cb3 = fig.colorbar(sc2,ax = ax1, aspect=10, ticks=MaxNLocator(5))
and remove this line:
cb3.ax.yaxis.set_major_locator(MaxNLocator(5,prune='upper'))
Old answers
Flip the order of these two lines:
cb3.update_ticks()
cb3.ax.yaxis.set_major_locator(MaxNLocator(5,prune='upper'))
and you should only five color intervals.
Alternatively, don't use set_major_locator at all and set the ticks directly in when making an instance:
cb3 = fig.colorbar(sc2,ax = ax1, aspect=10, ticks=[0, 2.5e-4, 5e-4, 7.5e-4, 1e-3 ])

Categories

Resources