I'm doing a jointplot with a basemap, the problem is that when I add the basemap the main plot doesn't have the same size of the marginal plots. I've tried with different parameters without luck. Does anyone have an idea?
import seaborn as sns
import matplotlib.pyplot as plt
import contextily as ctx
import pandas as pd
##exaplme of the data
coords={'longitud':[-62.2037376443, -62.1263309099, -62.1111660957, -62.2094232682, -62.2373117384, -62.4837603464,
-62.4030570833, -62.3975699059, -62.7017114116, -62.7830883096, -62.7786038141, -62.7683234105, -62.7490101452,
-62.7709656745, -63.1002199219, -63.1890252191, -63.1183018549, -63.069960016, -62.7957745659, -63.1715687622,
-63.2156105034, -63.0634381954, -63.2243260588, -63.1153871895, -63.1068292891, -63.103945266, -63.046202785,
-63.1002257551, -63.2076065143, -62.9766391316, -62.9639256604, -62.9911452446, -62.9819984159, -62.9693649898,
-63.066770885, -62.9867441519, -62.9566360192, -62.962616287, -62.835080907, -63.0704805194, -62.8796906301,
-63.0725050601, -63.2224345145, -63.1609069526, -63.0614466072, -62.8847887504, -63.1093652381, -62.822694115,
-63.211982035, -63.1689040153],
'latitud':[8.54644405234, 8.54344899107, 8.54223724187, 8.54290207992, 8.49122679072, 8.48386575122, 8.46450360179,
8.46404720757, 8.35310083084, 8.31701565261, 8.30258604829, 8.29974870902, 8.29281679496, 8.28939264064, 8.28785272804,
8.28221439317, 8.27978694565, 8.27864159366, 8.27634987807, 8.27619269053, 8.27236343925, 8.27258932351, 8.26833993531,
8.267530064, 8.26446669791, 8.26266392333, 8.2641092051, 8.26208837315, 8.26034269744, 8.26123972942, 8.25789799656,
8.25825378832, 8.25833002805, 8.25914612933, 8.2540499893, 8.25347956867, 8.2540932736, 8.25405171513, 8.2478564527,
8.24561857662, 8.2440865055, 8.24256528837, 8.24089278, 8.23877286416, 8.23782626443, 8.23865421655, 8.23733824299,
8.23477115627, 8.23552604027, 8.24327920905]}
df = pd.DataFrame(coords)
OSM_C = 'http://c.tile.openstreetmap.org/{z}/{x}/{y}.png'
joint_axes = sns.jointplot(
x='longitud', y='latitud', data=df, ec="r", s=5)
ctx.add_basemap(joint_axes.ax_joint,crs=4326,attribution=False,url=OSM_C)
adjust(hspace=0, wspace=0)
#plt.tight_layout()
plt.show()
Here is an approach that:
removes the axes sharing in the y-direction to be able to change the aspect to 'datalim'
sets the aspect to 'equal', 'datalim'
sets the y data limits of the marginal plot to be the same as the joint plot; this seems to need a redraw
The following code shows the idea (using imshow, as I don't have contextily installed):
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
coords = {'longitud' : [-62.2037376443, -62.1263309099, -62.1111660957, -62.2094232682, -62.2373117384, -62.4837603464, -62.4030570833, -62.3975699059, -62.7017114116, -62.7830883096, -62.7786038141, -62.7683234105, -62.7490101452, -62.7709656745, -63.1002199219, -63.1890252191, -63.1183018549, -63.069960016, -62.7957745659, -63.1715687622, -63.2156105034, -63.0634381954, -63.2243260588, -63.1153871895, -63.1068292891, -63.103945266, -63.046202785, -63.1002257551, -63.2076065143, -62.9766391316, -62.9639256604, -62.9911452446, -62.9819984159, -62.9693649898, -63.066770885, -62.9867441519, -62.9566360192, -62.962616287, -62.835080907, -63.0704805194, -62.8796906301, -63.0725050601, -63.2224345145, -63.1609069526, -63.0614466072, -62.8847887504, -63.1093652381, -62.822694115, -63.211982035, -63.1689040153],
'latitud' : [8.54644405234, 8.54344899107, 8.54223724187, 8.54290207992, 8.49122679072, 8.48386575122, 8.46450360179, 8.46404720757, 8.35310083084, 8.31701565261, 8.30258604829, 8.29974870902, 8.29281679496, 8.28939264064, 8.28785272804, 8.28221439317, 8.27978694565, 8.27864159366, 8.27634987807, 8.27619269053, 8.27236343925, 8.27258932351, 8.26833993531, 8.267530064, 8.26446669791, 8.26266392333, 8.2641092051, 8.26208837315, 8.26034269744, 8.26123972942, 8.25789799656, 8.25825378832, 8.25833002805, 8.25914612933, 8.2540499893, 8.25347956867, 8.2540932736, 8.25405171513, 8.2478564527, 8.24561857662, 8.2440865055, 8.24256528837, 8.24089278, 8.23877286416, 8.23782626443, 8.23865421655, 8.23733824299, 8.23477115627, 8.23552604027, 8.24327920905]}
df = pd.DataFrame(coords)
g = sns.jointplot(data=df, x='longitud', y='latitud')
ctx.add_basemap(g.ax_joint,crs=4326,attribution=False,url=OSM_C)
# g.ax_joint.imshow(np.random.rand(20, 10), cmap='spring', interpolation='bicubic',
# extent=[df['longitud'].min(), df['longitud'].max(), df['latitud'].min(), df['latitud'].max()])
for axes in g.ax_joint.get_shared_y_axes():
for ax in axes:
g.ax_joint.get_shared_y_axes().remove(ax)
g.ax_joint.set_aspect('equal', 'datalim')
g.fig.canvas.draw()
g.ax_marg_y.set_ylim(g.ax_joint.get_ylim())
plt.show()
You can still combine this approach with changing the figure's width or height, or adding more whitespace on top or below.
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?
How does matplotlib ensure that a dataset can be within plot with specified size.
How do i from a plot stored as numpy, How do i read the color of the pixels illustration a datapoint (0,4) - in the plot.
example:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
from PIL import Image
import librosa
import librosa.display
from matplotlib import cm
fig = plt.figure(figsize=(12,4))
min = -1.828067
max = 22.70058
data = np.random.uniform(low=min, high=max, size=(474,40))
librosa.display.specshow(data.T,sr=16000,x_axis='frames',y_axis='mel',hop_length=160,cmap=cm.jet)
plt.show()
raw_input("sadas")
convert = plt.get_cmap(cm.jet)
numpy_output_static = convert(data.T)
plt.imshow(numpy_output_static, aspect = 'auto')
plt.show()
raw_input("asds")
First plot being :
Second plot being:
so the first has been resized to plot size 12,4 where the last basically plots the same data but just using the data shape as size... how do i change that?
Librosa just performs pcolormesh according to the GitHub source code
You need to define another figure with its own size for the second figure.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
from PIL import Image
import librosa
import librosa.display
from matplotlib import cm
fig = plt.figure(figsize=(12,4))
min = -1.828067
max = 22.70058
data = np.random.uniform(low=min, high=max, size=(474,40))
librosa.display.specshow(data.T,sr=16000,x_axis='frames',y_axis='mel',hop_length=160,cmap=cm.jet)
plt.show()
raw_input("sadas")
convert = plt.get_cmap(cm.jet)
numpy_output_static = convert(data.T)
fig = plt.figure(figsize=(12,4))
plt.imshow(numpy_output_static, aspect = 'auto')
plt.show()
raw_input("asds")
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()