add top and Right spine to joint plot(regplot) in seaborn - 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.

Related

How do I select a line by clicking in Makie?

I want to be able to select a line on the plot by clicking on it. Ideally, when I click on any line, the number of that line will appear on the screen.
I wrote my code based on the tutorial, but there is no example with lines, so I did what I did. https://docs.makie.org/v0.19/documentation/events/index.html#point_picking
At the moment I have no idea what these numbers are telling me and why. They are not even coordinates of clicked points.
P.S. Actually it is just a starting point. I want to create event interaction on series and topoplots. But for now it would be great to find out the basics.
f = Figure(backgroundcolor = RGBf(0.98, 0.98, 0.98), resolution = (1500, 700))
ax = Axis(f[1, 1], xlabel = "Time [s]", ylabel = "Voltage amplitude [µV]")
N = 1:length(pos)
positions = Observable(rand(Point2f, 10))
xs = 0:0.01:10
ys = 0.5 .* sin.(xs)
lines!(xs, ys)
lines!(xs, ys * 2)
hidedecorations!(ax, label = false, ticks = false, ticklabels = false)
hidespines!(ax, :t, :r)
hlines!(0, color = :gray, linewidth = 1)
vlines!(0, color = :gray, linewidth = 1)
i = Observable(0)
on(events(f).mousebutton, priority = 2) do event
if event.button == Mouse.left && event.action == Mouse.press
plt, i[] = pick(f)
str = lift(i -> "$(i)", i)
text!(ax, 1, -0.5, text = str, align = (:center, :center))
end
end
f
Below are some examples of the interaction between clicking and the number displayed (the red dot is where I click).
Check out the mouseposition variable here:
https://docs.makie.org/stable/api/#Events
or the registerInteraction! function here:
https://docs.makie.org/v0.19/examples/blocks/axis/index.html#registering_and_deregistering_interactions
You can use them both as below:
using GLMakie
f = Figure(backgroundcolor = RGBf(0.98, 0.98, 0.98), resolution = (1500, 700))
ax = Axis(f[1, 1], xlabel = "Time [s]", ylabel = "Voltage amplitude [µV]")
#N = 1:length(pos)
positions = Observable(rand(Point2f, 10))
xs = 0:0.01:10
ys = 0.5 .* sin.(xs)
lines!(xs, ys)
lines!(xs, ys * 2)
hidedecorations!(ax, label = false, ticks = false, ticklabels = false)
hidespines!(ax, :t, :r)
hlines!(0, color = :gray, linewidth = 1)
vlines!(0, color = :gray, linewidth = 1)
register_interaction!(ax, :my_interaction) do event, axis
if event.type === MouseEventTypes.leftclick
println("Graph axis position: $(event.data)")
end
end
i = Observable(0)
on(events(f).mousebutton, priority = 2) do event
if event.button == Mouse.left && event.action == Mouse.press
plt, i[] = pick(f)
str = lift(i -> "$(i)", i)
text!(ax, 1, -0.5, text = str, align = (:center, :center))
#show mouseposition(f)
end
end
f
Note that for some reason (perhaps it sees the first click as a selection?) Makie does not start registering the interaction on the graph until the first click within the graph, unlike the clicks on the figure which are all shown even the first one.

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]

Yaw rotation of gear object in vpython

I was wondering how to yaw gear object about Y-axis in vpython. I have been following some tutorials and I have managed to rotate the gear. The gear rotates about Z axis in vpython. I want the gear to remain rotating about Z axis but I would like to yaw the gear around Y-axis. When xxx.rotate(axis=vector(0,0,1), it works as it should do. As soon as I alter anything it goes crazy. I am not sure what xxx.rotate(origin) is meant to do. In my case, I have messed around with the origin vector but it doesn't make any sense to me. I am not sure if the origin vector expects parameter values in x,y,z or some other sequence. I hope I am making makes sense.
The code below is a working code and you can see what I am trying to do here. I have been debugging for a while so please ignore unnecessary comments.
'
# https://www.youtube.com/watch?v=0Sw8sxsN984
# https://www.youtube.com/watch?v=MJiVtz4Uj7M
from vpython import *
import numpy as np
axisOpac = 0.4
def makeAxes(length):
global axes
xaxis = arrow(pos=vector(0, 0, 0), axis=length*vector(1,0,0), shaftwidth = 0.1*(length), color=color.red, opacity = axisOpac)
negXaxis = xaxis.clone()
negXaxis.axis *= -1
yaxis = arrow(pos=vector(0, 0, 0), axis=length*vector(0,1,0), color=color.green, opacity = axisOpac)
negYaxis = yaxis.clone()
negYaxis.axis *= -1
zaxis = arrow(pos=vector(0, 0, 0), axis=length*vector(0,0,1), color=color.magenta, opacity = axisOpac)
negZaxis = zaxis.clone()
negZaxis.axis *= -1
fudge = 0.01*length
xlabel = label(text = "x", color = xaxis.color, pos=xaxis.axis+vector(0, fudge, 0),box = False)
ylabel = label(text = "y", color = yaxis.color, pos=yaxis.axis+vector(0, fudge, 0),box = False)
zlabel = label(text = "-z", color = zaxis.color, pos=zaxis.axis+vector(0, fudge, 0),box = False)
# To make axes visible or invisible
axes = [xaxis, negXaxis, yaxis, negYaxis, zaxis, negZaxis, xlabel, ylabel, zlabel]
return
makeAxes(1)
g = shapes.gear(n = 20)
gear1 = extrusion (path = [vector(0, 0, 0), vector(0, 0, 0.1)], shape=g, opacity = 0.4)
# gear1.axis = vector(0, 0, 0)
debugArrow=arrow(length=6,shaftwidth=.1,color=color.white,axis=vector(0,0,0))
gearAxisArrow=arrow(shaftwidth=.1, color=color.red)
inputYawAngleYaxis = 0 # int(input("Enter an angle: "))
while True:
for cir in np.arange(0, 2*np.pi, 0.01):
rate(10)
# sleep(1)
pitch=0
# k = vector(cos(yaw)*cos(pitch), sin(pitch),sin(yaw)*cos(pitch)) ''' with pitch input '''
k = vector(cos(cir), 0 ,sin(cir)) # ''' without pitch input '''
y=vector(0,0,0)
s=cross(k,y)
v=cross(s,k)
rad = radians(45)
# gear1.axis = vector(1.23, -1.77418, 0) #vector(cos(inputYawAngleYaxis * pi/180), sin(pitch),sin(inputYawAngleYaxis* pi/180)*cos(pitch))
# gear1.pos = vector(-2.94957, 0, 2.70185)
# Gear Pos0: <0.707107, 0, 0.707107> Gear Axis0: <2.15647, 0.101243, -0.00237659>
gear1.pos = vector(0.707107, 0, 0.707107)
# gear1.pos = debugArrow.axis #frontArrow.axis # k # vector(0.707107, 0, 0.707107)
gear1.rotate(angle = -0.1, axis = vector(0, 0, 1), origin = vector(0, 0, 1 ))
# gear1.axis = vector(cos(radians(-45)), 0, sin(radians(-45)))
''' DebugArrow represents the position of the gear's center '''
debugArrow.axis = vector(cos(rad), 0, sin(rad))
''' Arrow inside the gear to track rotational axis of gear - This is to debug the yaw issue facing with gear object'''
gearAxisArrow.pos = gear1.pos
gearAxisArrow.axis = gear1.axis # vector(cos(radians(-45)), 0, sin(radians(-45))) # gear1.axis
gearAxisArrow.length = gear1.length/2
## Debugg
# print("Front Arrow Axis: ", frontArrow.axis, " K vec: ", k, " Ball pos: ", ball.pos )
print("Gear Pos0: ", gear1.pos, " Gear Axis0: ", gear1.axis, "gearAxisArrow: ", gearAxisArrow.pos, "gearAxisArrow: ", gearAxisArrow.axis)
'
I don't understand "I want the gear to remain rotating about Z axis but I would like to yaw the gear around Y-axis". If by "yaw" you mean that the axis of the gear should rotate about the y axis (while the gear itself rotates about that rotating axis), then obviously the axis of the gear can't remain in the direction of the z axis. Instead, the axis of the gear has to rotate. If it's of any help, here is the relevant page of the documentation:
https://www.glowscript.org/docs/VPythonDocs/rotation.html

Adding tick marks and line on barplot

I need help adding tick marks to my barplot. I would like an X-axis with tick marks in intervals of 100. I would also like to add a vertical red line at X=1350. How can I add that to the following code:
H <- c(1350, 1436) # Create the data for the chart, cont3.#
M <- c(
"Target
Attendance",
"Actual
Attendance"
)
c <-barplot(H, col =c("slategray3","dodgerblue4" ),
names.arg = M, horiz = TRUE,
family="Arial", border = NA,
xlim = range(0,1600),
axes = TRUE, las=1)
One can use the axis() and abline() functions to modify the base graphics:
barplot(H, col =c("slategray3","dodgerblue4" ),
names.arg = M, horiz = TRUE,
family="Arial", border = NA,
xlim = range(0,1600),
axes = FALSE, las=1)
axis(1, at=seq(0, 1500, 100))
abline(v=1350, col="red")
Add the "lwd=" option to the abline function to change the line's width.

Get an image of a text with optimized font size and centering in Matlab?

I have a string chain of characters that I would like to display as big as possible within a rectangle frame, in a centered way. I know :
how many characters maximum can have my input
the dimensions of the rectangle
It has to :
find the best font size and displays the result.
Here is the MATLAB code
color = 'k';
txt = '1';
howManyCharMaximum = 7;
boxWidth = 250;
boxHeight = 100;
%% comput: Now I assume one char is as wide as tall
howManyChar = strlength(txt);
marginHoriz = mod(boxWidth,howManyCharMaximum); %in points
subRectangle.width = (boxWidth-marginHoriz)/howManyCharMaximum;
subRectangle.height = boxHeight;
[fontSize,idx] = min([subRectangle.width, subRectangle.height]); %the largest square that fits in a rectangle
%%
hFigure = figure('MenuBar', 'none', ...
'ToolBar', 'none', ...
'Units', 'points', ...
'Position', [0 0 boxWidth boxHeight], ... % x y from bottom left of screen to botleft of the fig
'Color', 'w');
hAxes = axes; hAxes.Visible = 'off';
%pos:=botleft vertex of the string
switch(idx)
case 1
x = floor((boxWidth-howManyChar*fontSize)/2);
y = floor((boxHeight-fontSize)/2);
case 2
addMarginHoriz = (subRectangle.width-subRectangle.height)*howManyCharMaximum;
x = floor((boxWidth-howManyChar*fontSize)/2);
y = 0;
end
hText = text(x, y, ...
txt, ...
'Units', 'points', ...
'FontSize', fontSize, ...
'HorizontalAlignment', 'left', ...
'VerticalAlignment', 'middle', ...
'Color', color);
But for some reasons I can't figure out, this is what it returns unfortunately -- a decentered character:
Would anyone know where I did a mistake pleaase ? By thanking you in advance.
I used normalized units for text as its lot easier to find the center and then it worked with the proper alignment. Note that a slight offset will still exist because actual figure grid has more space on left then right and at bottom then top. You can experimentally adjust it if you wish
color = 'k';
txt = '18998';
%howManyCharMaximum = 7; I didnt use this one
boxWidth = 250;
boxHeight = 100;
%% comput: Now I assume one char is as wide as tall
howManyChar = strlength(txt);
%marginHoriz = mod(boxWidth,howManyCharMaximum); %in points
subRectangle.width = (boxWidth)/howManyChar;
subRectangle.height = boxHeight;
[fontSize,idx] = min([subRectangle.width, subRectangle.height]); %the largest square that fits in a rectangle
%%
hFigure = figure('MenuBar', 'none', ...
'ToolBar', 'none', ...
'Units', 'points', ...
'Position', [0 0 boxWidth boxHeight], ... % x y from bottom left of screen to botleft of the fig
'Color', 'w');
hAxes = axes; hAxes.Visible = 'off';
%plot(0,0)
%pos:=botleft vertex of the string
x = floor(boxWidth/2);
y = floor(boxHeight/2)
hText = text(0.5, 0.5, ...
txt, ...
'Units', 'normalized', ...
'FontSize', fontSize, ...
'HorizontalAlignment', 'center', ...
'VerticalAlignment', 'middle', ...
'Color', color);

Resources