How to create subplots with seaborn? I am not achieving my expected result [duplicate] - seaborn

This question already has an answer here:
seaborn is not plotting within defined subplots
(1 answer)
Closed 6 months ago.
I am trying to create a simple subplot in seaborn using 1 row 2 columns. But am not getting the expected result. Instead my figures are displaying separately. Please help.
df = sns.load_dataset("tips")
fig, axes = plt.subplots(nrows = 1, ncols = 2, figsize = (15,6))
sns.relplot(x = "tip", y= "total_bill" , data = df , hue = "smoker", kind = "line",
hue_order = ["No", "Yes"], ax = axes[0])
sns.catplot(x = "tip", data = df, kind = "point", ax = axes[1])
Result

Both the plots you are using - relplot and catplot are figure level plots. They cannot be used as sub plots. That is the reason you are seeing the initial blank plots and then the individual relplot and catplot.
You need to use lineplot and pointplot respectively instead, which will allow you to use the subplots. Note that kind='line' is no longer required, so it has been commented out in the code below...
df = sns.load_dataset("tips")
fig, axes = plt.subplots(nrows = 1, ncols = 2, figsize = (15,6))
sns.lineplot(x = "tip", y= "total_bill" , data = df , hue = "smoker", #kind = "line",
hue_order = ["No", "Yes"], ax = axes[0])
sns.pointplot(x = "tip", data = df, kind = "point", ax = axes[1])
Plot

Related

matplotlib pie chart cmap color variation according to correlation red , white , blue [-1,0,1]

I am struggling to make a pie chart with only three color variations according to correlation values between two quantities, the color only varies between red(-1 peak), white (0), and blue(+1 peak). this is my code, I copied some parts from StackOverflow.
import NumPy as np
import matplotlib.pyplot as plt
def mypie(slices, labels, colors, val):
colordict = {}
for l, c in zip(labels, colors):
colordict[l] = c
fig = plt.figure(figsize=[10, 10])
ax = fig.add_subplot(111)
# , autopct=make_autopct(slices))
pie_wedge_collection = ax.pie(slices, labels=labels, labeldistance=1.05)
for pie_wedge in pie_wedge_collection[0]:
pie_wedge.set_edgecolor('white')
pie_wedge.set_facecolor(colordict[pie_wedge.get_label()])
titlestring = val
ax.set_title(titlestring)
return fig, ax, pie_wedge_collection
for idx,val in enumerate(pf.index):
slices = np.abs(pf.iloc[idx,:])
labels = oct12.columns
label_df = pd.DataFrame(labels, columns=['labels'])
label_df['slices'] = slices
label_df['label'] = label_df['labels'] + ': ' + label_df['slices'].apply(lambda x: '{:.2g}'.format(x))
# sort by slices
label_df = label_df.sort_values(by='slices', ascending=False)
cmap = plt.cm.prism
colors = cmap(np.linspace(1.024, 0.004, len(slices)))
labels = oct12.columns
sizes = [30 for i in range(len(oct12.columns))]
fig, ax, pie_wedge_collection = mypie(sizes, label_df.label, colors, val)
plt.show()
This is what I am getting, here I am hardcoding the colors, however, I need to have color variations between [red, white, blue] according to the variations in correlation in slices variable.
However, I want something like below:

Trying to get a plotly graph object including both scatter and image to change xtick labels

I am creating a plotly figure, overlapping rectangles on an image and I want to change the xticks.
Example Code:
a = 255*np.random.random((28,28))
pil_img = Image.fromarray(a).convert('RGB')
fig2 = go.Figure(data = [go.Scatter(x=[0,10,10,0], y=[0,0,10,10], fill="toself"),go.Image(z=pil_img)])
fig2.show()
Instead of the ticks being the number of pixels (0-28) I want them to be let's say from 0.2 to 3 in increments of 0.1 [0.2,0.3,...3] so that the length is still 28 but the ticks aren't [0,1,2] but rather [0.2,0.3,..3]
Thanks!
Following this documentation page, one way to achieve it is:
import numpy as np
from PIL import Image
import plotly.graph_objects as go
N = 28
a = 255 * np.random.random((N, N))
pil_img = Image.fromarray(a).convert('RGB')
fig = go.Figure(data = [go.Scatter(x=[0,10,10,0], y=[0,0,10,10], fill="toself"),go.Image(z=pil_img)])
fig.update_layout(
xaxis = dict(
tickmode = 'array',
tickvals = np.arange(N),
ticktext = ["{:.1f}".format(t) for t in np.linspace(0.3, 3, N)]
),
yaxis = dict(
tickmode = 'array',
tickvals = np.arange(N),
ticktext = ["{:.1f}".format(t) for t in np.linspace(0.3, 3, N)]
)
)
fig

Fix aspect ratio of a scatter plot with an image

I've to plot multiple scatter and table in a grid space and I'm having a couple of issues with the relative position but most important with defining and maintaining the aspect ratio of the scatter plot.
I've written a script with "fake" data on it to describe my problem and a minimum "not working" example below.
What I have is a dataframe with x, and y positions of objects, and what I want to do is to put the corresponding image below.
Since the image can have an arbitrary aspect ratio I need to read the aspect ratio and construct the scatter plot in that way but I'm unable to make it work.
Another problem is connected with the invert_xaxis and invert_yaxis that don't work (I need that command since the scatter data are inverted.
I've used the following commands, and as far as I've understood each of them should block the aspect ratio of the scatter plot to the same ratio of the figure but they do not work.
The aspect ratio becomes corrected only when the figure is plotted but that eliminates the effect of axis inversion.
I've had a similar problem with setting the aspect ratio of plots without the addition of a figure, sometimes it worked but not with tight_layout.
It is obvious that I'm missing something important....but I'm unable to figure it out.
This is the fake data code:
###############################################################################
# fake data
#general data aspect ratio
image_height= 5 #4270
image_width = 10 # 8192
pix2scale = 0.3125
data_AR = image_height / image_width
#random data generation
data_width = image_width* pix2scale
data_height = image_height * pix2scale
data1x = np.random.uniform(-data_width/2, data_width/2, size=(40))
data1y = np.random.uniform(-data_height/2, data_height/2, size=(40))
data2x = np.random.uniform(-data_width/2, data_width/2, size=(40))
data2y = np.random.uniform(-data_height/2,data_height/2, size=(40))
temp_df1 = pd.DataFrame([data1x,data1y,['random1']*40],index = ['x','y','label']).T
temp_df2 = pd.DataFrame([data2x,data2y,['random2']*40],index = ['x','y','label']).T
df = pd.concat([temp_df1,temp_df2],axis = 0, ignore_index = True)
del temp_df1, temp_df2
#sample image generation of variable aspect ratio
img_size = (image_height, image_width)
R_layer = np.ones(shape= img_size)*0.50
G_layer = np.ones(shape= img_size)*0.50
B_layer = np.ones(shape= img_size)*0.50
A_layer = np.ones(shape= img_size)
img = np.dstack([R_layer,G_layer,B_layer,A_layer])
#add a mark at the top left of the image
for k in range(0,3):
for i in range(0,int(image_width*0.2*data_AR)):
for j in range(0,int(image_width*0.2)):
img[i,j,k] = 0
#add a mark at the center of the image
# get center coordinates of the image
center = [[2, 4], [2, 5]]
for k in range(0,3):
for point in center:
if k == 0:
img[point[0],point[1],k] = 1
else:
img[point[0],point[1],k] = 0
#show image
fig, ax = plt.subplots()
ax.imshow(img)
###############################################################################
this is the code that generates the image:
#%%
# sample code
# at this point Iìve already loaded the image, the pix2scale value
# and the df containing data points
#read image aspect ratio
img_AR = img.shape[0]/img.shape[1]
pixel_width = img.shape[1]
pixel_height = img.shape[0]
# each pixel correspond to 0.3125 unit (mm)
pix2scale = 0.3125
#define image position
#the center of the image need to be placed at (0,0)
#bottom left corner
left = - (pixel_width * pix2scale)/2
bottom = - (pixel_height * pix2scale)/2
right = left + (pixel_width * pix2scale)
top = bottom + (pixel_height * pix2scale)
extent = [left,right,bottom,top]
#figure definition
figure_width = 15 #inch
figure_AR = 1
scatter_AR = img_AR
#initialize figure
fig_s= plt.figure(figsize = (figure_width,figure_width*figure_AR))
gs = plt.GridSpec (3,3)
#scatter plot in ax1
ax1 = fig_s.add_subplot(gs[:2,:2])
g = sns.scatterplot( data = df,
x = 'x',
y = 'y',
hue = 'label',
ax =ax1
)
ax1.invert_xaxis()
ax1.invert_yaxis()
#resize the figure box
box = ax1.get_position()
ax1.set_position([box.x0,box.y0,box.width*0.4,box.width*0.4*scatter_AR])
ax1.legend(loc = 'center left', bbox_to_anchor = (1,0.5))
ax1.set_title('Inclusions Scatter Plot')
ax1.set_aspect(scatter_AR)
#plt image
ax1.imshow(img,extent = extent)
#scatter plot
ax2 = fig_s.add_subplot(gs[2,:2])
g = sns.scatterplot( data = df,
x = 'x',
y = 'y',
hue = 'label',
ax =ax2
)
#resize the figure box
box = ax2.get_position()
ax2.set_position([box.x0,box.y0,box.width*0.4,box.width*0.4*scatter_AR])
ax2.legend(loc = 'center left', bbox_to_anchor = (1,0.5))
ax2.set_title('Inclusions Scatter Plot')
ax2.set_aspect(scatter_AR)
ax2.imshow(img,extent = extent)
#scatter plot
ax3 = fig_s.add_subplot(gs[1,2])
g = sns.scatterplot( data = df,
x = 'x',
y = 'y',
hue = 'label',
ax =ax3
)
#resize the figure box
box = ax3.get_position()
ax3.set_position([box.x0,box.y0,box.width*0.4,box.width*0.4*scatter_AR])
ax3.legend(loc = 'center left', bbox_to_anchor = (1,0.5))
ax3.set_title('Inclusions Scatter Plot')
ax3.set_aspect(scatter_AR)
ax3.imshow(img,extent = extent)
#add suptitle to figure
fig_s.suptitle('my title',fontsize= 22)
fig_s.subplots_adjust(top=0.85)
# #make it fancy
for i in range(3):
fig_s.tight_layout()
plt.pause(0.2)
I've plotted multiple grid because I wanted to test the tight_layout().
[enter image description here][2]

add top and Right spine to joint plot(regplot) in seaborn

This is the current code I have
sns.set_style("whitegrid",{'axes.spines.top': True, 'axes.spines.right': True,'axes.linewidth': 2, 'axes.edgecolor':'black'})
g = sns.JointGrid(x=station1,y=station2,data = df, xlim = xlim, ylim = ylim,space =1)
sns.set_style("whitegrid",{'axes.spines.top': True, 'axes.spines.right': True,'axes.linewidth': 2, 'axes.edgecolor':'black'})
g.plot_joint(sns.regplot, fit_reg = False, truncate = False, robust = False, label = 'regression', color = 'darkorange',)
g.plot_marginals(sns.histplot, kde = True, color = 'darkorange')
# g.ax_joint.legend({'Pearson_R: %.4f'%r, 'x_axis mean:%.3f; std:%.3f'%(d1.df[par_x][idx_1].mean(),d1.df[par_x][idx_1].std()),'y_axis mean:%.3f; std:%.3f'%(d2.df[par_y][idx_2].mean(),d2.df[par_y][idx_2].std())})
# g.ax_joint.legend({'y = %.3f x + %.3f \nR^2: %.4f'%(popt[0],popt[1],r**2)})
g.ax_joint.legend({'$R^2$:%.4f'%(r**2)}, loc = 'upper right')
g.ax_joint.plot(np.linspace(xlim[0],xlim[1],100),linear(np.linspace(xlim[0],xlim[1],100),1,0), linewidth = 0.7, ls = '-.', color = 'black')
I am trying to add spines to Top and left of a joint grid plot in seaborn, However, the best I am able to do is
2 sided plot
is there a way to add a boarder to the top and Right side of the main plot and add right top and left of the sub plots? Thanks.

No display from using subplot after wavedec2 in MATLAB

I followed the MathWorks tutorial on wavedec2 and am unable to properly display any of the coefficient or approximation subplots.
Can anyone suggest how I fix this so it displays the approximation and detail subplots correctly?
This is what I have so far:
% Load image ‘Sample.tif’ and convert it into a grayscale image, denoted with ‘img1’
I = imread('Sample.tif');
img1 = rgb2gray(I);
% Decompose img1 with wavelet transform using function wavedec2
% Perform decomposition at level 2
% of X using haar.
[C,S] = wavedec2(I,2,'haar');
[H1,V1,D1] = detcoef2('all',C,S,1);
A1 = appcoef2(C,S,'haar',1);
V1img = wcodemat(V1,255,'mat',1);
H1img = wcodemat(H1,255,'mat',1);
D1img = wcodemat(D1,255,'mat',1);
A1img = wcodemat(A1,255,'mat',1);
[H2,V2,D2] = detcoef2('all',C,S,2);
A2 = appcoef2(C,S,'haar',2);
V2img = wcodemat(V2,255,'mat',1);
H2img = wcodemat(H2,255,'mat',1);
D2img = wcodemat(D2,255,'mat',1);
A2img = wcodemat(A2,255,'mat',1);
subplot(2,2,1);
imagesc(A1img);
colormap red(255);
title('Approximation Coef. of Level 1');
subplot(2,2,2);
imagesc(H1img);
title('Horizontal detail Coef. of Level 1');
subplot(2,2,3);
imagesc(V1img);
title('Vertical detail Coef. of Level 1');
subplot(2,2,4);
imagesc(D1img);
title('Diagonal detail Coef. of Level 1');
The output is here, and all subplots are completely white:
Sample.tif is here:
The datatype of your images is double but the range of value of your images is [0 255] so you have to cast your picture into the good datatype. [0 255] correspond to the range of the uint8 datatype, so you can simply write:
imagesc(uint8(A1img));
or
A1img = uint8(A1img);

Resources