Show scatter plot and 2D histogram same figure - seaborn

I have the following scatter plot created with seaborn.scatterplot:
where I used the code:
seaborn.scatterplot(x=X1, y=Y2, s=5, color=".15")
Now I want to add a 2D histogram generated from related data but described by the same reference frame. The histogram looks like the following when calculated independently:
where I have used:
seaborn.jointplot(x=X2, y=Y2,kind="hex",marginal_kws=dict(bins=100))
So, how can I merge both plots?

sns.jointplot() returns a JointGrid which has attributes ax_joint, ax_marg_x, and ax_marg_y which can be used to modify the plot.
sns.scatterplot() can accept an ax as a parameter on which to draw the scatter plot.
A combined operation could look like:
import seaborn as sns
# ... read in or generate data
g = sns.jointplot(x=X2, y=Y2, kind="hex", marginal_kws=dict(bins=100))
sns.scatterplot(x=X1, y=Y2, s=5, color=".15", ax=g.ax_joint)

Related

Plot does not highlight all the unique values of a column represented by hue

My dataframe has a column 'rideable_type' which has 3 unique values:
1.classic_bike
2.docked_bike
3.electric_bike
While plotting a barplot using the following code:
g = sns.FacetGrid(electric_casual_type_week, col='member_casual', hue='rideable_type', height=7, aspect=0.65)
g.map(sns.barplot, 'day_of_week', 'number_of_rides').add_legend()
I only get a plot showing 2 unique 'rideable_type' values.
Here is the plot:
As you can see only 'electric_bike' and 'classic_bike' are seen and not 'docked_bike'.
The main problem is that all the bars are drawn on top of each other. Seaborn's barplots don't easily support stacked bars. Also, this way of creating the barplot doesn't support the default "dodging" (barplot is called separately for each hue value, while it would be needed to call it in one go for dodging to work).
Therefore, the recommended way is to use catplot, a special version of FacetGrid for categorical plots.
g = sns.catplot(kind='bar', data=electric_casual_type_week, x='day_of_week', y='number_of_rides',
col='member_casual', hue='rideable_type', height=7, aspect=0.65)
Here is an example using Seaborn's 'tips' dataset:
import seaborn as sns
tips = sns.load_dataset('tips')
g = sns.FacetGrid(data=tips, col='time', hue='sex', height=7, aspect=0.65)
g.map_dataframe(sns.barplot, x='day', y='total_bill')
g.add_legend()
When comparing with sns.catplot, the coinciding bars are clear:
g = sns.catplot(kind='bar', data=tips, x='day', y='total_bill', col='time', hue='sex', height=7, aspect=0.65)

Scatterplot with x axis only

I have a dataframe 'Spreads' where one of the columns is 'HY_OAS'. My goal is to draw a horizontal line (basically representing a range of values for 'HY_OAS') and plot the column mean on that line. In addition, I wanted the x axis min/max to be the min/max for that column and I'd like to include text boxes annotating the min/max. The problem is I'm not sure how to proceed because all I have is the below. Thanks for any and all help. The goal is the second image and the current code is the first image.
fig8 = px.scatter(x=[Spreads['HY_OAS'].mean()], y=[0])
fig8.update_xaxes(visible=True,showticklabels=False,range=[Spreads['HY_OAS'].min(),Spreads['HY_OAS'].max()])
fig8.update_yaxes(visible=True,showticklabels=False, range=[0,0])
Following what you describe and what you have coded
generate some sample data in a dataframe
scatter values along x-axis and use constant for y-axis
add mean marker
format figure
add required annotations
import numpy as np
import plotly.express as px
import pandas as pd
# simulate some data
Spreads = pd.DataFrame({"HY_OAS": np.sin(np.random.uniform(0, np.pi * 2, 50))})
# scatter values along x-axis and and larger point for mean
fig = px.scatter(Spreads, x="HY_OAS", y=np.full(len(Spreads), 0)).add_traces(
px.scatter(x=[Spreads.mean()], y=[0])
.update_traces(marker={"color": "red", "size": 20})
.data
)
# fix up figure config
fig.update_layout(
xaxis_visible=False,
yaxis_visible=False,
showlegend=False,
paper_bgcolor="rgba(0,0,0,0)",
plot_bgcolor="rgba(0,0,0,0)",
)
# finally required annootations
fig.add_annotation(x=Spreads["HY_OAS"].mean(), y=0, text=Spreads["HY_OAS"].mean().round(4))
fig.add_annotation(x=Spreads["HY_OAS"].min(), y=0, text=Spreads["HY_OAS"].min().round(2), showarrow=False, xshift=-20)
fig.add_annotation(x=Spreads["HY_OAS"].max(), y=0, text=Spreads["HY_OAS"].max().round(2), showarrow=False, xshift=20)
straight line
build base figure as follows
then same code to add annotations and configure layout
fig = px.line(x=[Spreads["HY_OAS"].min(), Spreads["HY_OAS"].max()], y=[0,0]).add_traces(
px.scatter(x=[Spreads.mean()], y=[0])
.update_traces(marker={"color": "red", "size": 20})
.data
)

Using Custom Scale function for ReCharts or d3-scale

I want to display Weibull analysis plot using Recharts. For Weibull analysis, formula for Y-Axis Scale is as:
ln(-ln(1-p))
where p=(i-0.3)/(n+0.4) and i is the rank of the observation. This scale is chosen in order to linearize the resulting plot for Weibull data. You can have a look at the Y Axis log scale as shown in the example graph below.
I tried standard scaleLog() but I need to customize the log function.
const y_scale = scaleLog().range([0, 100]);
Also, one of the recharts issue shows an option of function while defining scale, but that also does not seem to work.
https://github.com/recharts/recharts/issues/305
Would be great if someone could help with the way to implement custom scale functions.
Example of Weibull Graph:
Recharts seems to have added exactly what you were searching on the documentation of YAxis
https://recharts.org/en-US/api/YAxis#scale
import { scaleLog } from 'd3-scale';
const scale = scaleLog().base(Math.E);
...
<YAxis scale={scale} />
...

Python regionprops sci-kit image

I am using sci-kit image to get the "regionprops" of a segmented image. I then wish to replace each of the segment labels with their corresponding statistic (e.g eccentricity).
from skimage import segmentation
from skimage.measure import regionprops
#a segmented image
labels = segmentation.slic(img1, compactness=10, n_segments=200)
propimage = labels
#props loop
for region in regionprops(labels1, properties ='eccentricity') :
eccentricity = region.eccentricity
propimage[propimage==region] = eccentricity
This runs, but the propimage values do not change from their original labels
I have also tried:
for i in range(0,max(labels)):
prop = regions[i].eccentricity #the way to cal a single prop
propimage[i]= prop
This delivers this error
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
I am a recent migrant from matlab where I have implemented this, but the data structures used are completely different.
Can any one help me with this?
Thanks
Use ndimage from scipy : the sum() function can operate using your label array.
from scipy import ndimage as nd
sizes = nd.sum(label_file[0]>0, labels=label_file[0], index=np.arange(0,label_file[1])
You can then evaluate the distribution with numpy.histogram and so on.

How do I create a categorical legend for imagesc with square legend symbols?

I have with 5 different values and I would like to create a legend ?
These are continuous data, I need small coloured squares !
How to add legend in imagesc plot in matlab Something like this but with squares, I tried replacing "line" by "rectangle" but that's not the trick apparently !
Thank you
I just used your linked example code and modified it a little:
N=4; % # of data types, hence legend entries
Data = randi(N,30,30); % generate fake data
imagesc(Data) % image it
cmap = jet(N); % assigen colormap
colormap(cmap)
hold on
markerColor = mat2cell(cmap,ones(1,N),3);
L = plot(ones(N), 'LineStyle','none','marker','s','visible','off');
set(L,{'MarkerFaceColor'},markerColor,{'MarkerEdgeColor'},markerColor);
legend('A','B','C','D')
The trick is to use markers instead of the line itself.
it returns:

Resources