Superimposing Images in Catplot - python

I am attempting to superimpose dot plots on top of a bar graph. Both types of plots have been generated using seaborn's catplot function.
Scatter-plot Code:
dotplot2 = sns.catplot(x="Group", y="MASQ_Score", col= "MASQ_Item", units="subject", aspect=.6, hue="Group", ci = 68, data=df_reshaped)
Resulting Plot Image:
Bar-plot Code:
barplot2 = sns.catplot(x="Group", y="MASQ_Score", hue='Group', kind="bar", col= "MASQ_Item", units="subject", aspect=.6, ci = 68, data=df_reshaped)
Resulting Plot Image:
Does anyone know if there is a way to superimpose the scatter-plot data on top of the bar-plot? So that both types of information are conveniently visible.

Based on #ImportanceOfBeingErnest comment, here is a working solution with open data using the map_dataframe method from FacetGrid:
import seaborn as sns
tips = sns.load_dataset("tips")
g = sns.FacetGrid(tips, col="time")
g.map_dataframe(sns.stripplot,x="sex", y="total_bill")
g.map_dataframe(sns.boxplot,x="sex", y="total_bill",boxprops={'facecolor':'None'},showfliers = False)
The stirpplot and boxplot can easily be replaced by other seaborn components like swarmplot or violinplot.

What you are plotting is not a scatter plot, it is a stirpplot. As #Rachid Riad shows. If what you are looking for is to make a barplot instead of a boxplot, you just have to change that line to:
sns.barplot()
I would personally recommend using boxplot and swarmplot.

Related

Overriding Seaborn legend

I made a line plot using seaborn's relplot and I wanted to customize my legend labels. For some reason when I do this, It creates another legend with out deleting the old one. How do I get rid of the initial legend (The legend with title "Sex")? Also how do I add a legend title to my new legend?
Here is the code I used to generate my plot:
plt.figure(figsize=(12,10))
sns.relplot(x='Year',y = 'cancer/100k pop' , data = dataset_sex,hue="Sex", kind="line",ci=None)
title_string = "Trend of Cancer incidencies by Sex "
plt.xlabel('Years')
plt.title(title_string)
plt.legend(['Men','Women'])
regplot is a figure-level function, and returns a FacetGrid. You can remove its legend via g.legend.remove().
import matplotlib.pyplot as plt
import seaborn as sns
tips = sns.load_dataset("tips")
g = sns.relplot(data=tips, x="total_bill", y="tip", hue="day")
g.legend.remove()
plt.legend(['Jeudi', 'Vendredi', 'Samedi', 'Dimanche'])
plt.show()
This code has been tested with seaborn 0.11. Possibly you'll need to upgrade. To add a title to the legend: plt.legend([...], title='New title').
Note that plt.legend(...) will create the legend inside the last (or only) subplot. If you prefer the figure-level legend next to the plot, to change the legend labels, you can call g.add_legend(labels=[...], title='new title') after having removed the old legend.
PS: Adding legend=False to sns.relplot() will not create the legend entries. So, you'll need to recreate both the legend markers and their labels, while you lost the information of which colors were used.

Plotting a reference line over facet plots

I need to scatter plot data with its own line by type with a comparison to a reference line for each facet. I am wrestling with getting the line equation y=8x+10 to plot on each facet plot.
import pandas as pd
import seaborn as sns
sns.lmplot(x="18O‰ VSMOW", y="D‰ VSMOW", hue="Type",
col="Type", col_wrap=2, data=df)
My goal is to enable easy comparison of each Type to a known general relationship. Below, I drew in what I would like on the top two plots:
As of matplotlib 3.3, use axline() to easily plot reference lines.
Figure-level functions like lmplot return a FacetGrid, so store the grid to access the facets.
Either use FacetGrid.map_dataframe() to apply axline to each facet:
# store underlying facet grid
g = sns.lmplot(x='total_bill', y='tip', col='day', hue='day', col_wrap=2, data=df)
# apply axline to each facet (y = 0.18*x - 0.3)
g.map_dataframe(lambda data, **kws: plt.axline((0, -0.3), slope=0.18))
Or iterate the facets manually via g.axes.flat:
for ax in g.axes.flat:
ax.axline((0, -0.3), slope=0.18) # y = 0.18*x - 0.3

Is it possible to add KDE estimation to hisgram in a pairplot plot with seaborn?

I'm ploting a pairplot plot with seaborn (See figure). I would like to add to the histograms the KDE estimations. Is it possible? Besides, is it possible to make the histogram less opaque in order to better see both of them?
Thank you
If I understand correctly, this might address your requirements
import seaborn as sns
sns.set(style="ticks")
df = sns.load_dataset("iris")
p = sns.PairGrid(df, vars=['sepal_length', 'sepal_width'], hue="species")
p = p.map_offdiag(sns.scatterplot)
p = p.map_diag(sns.distplot, hist=True, kde=True, hist_kws={'alpha':0.5})
Here is the screenshot..

How do I overlay different kinds of graph in Seaborn?

I'm trying to get two graphs into the same fig, using different y-axes, and it works fine when I use the same kind of plot (two barplots or two lineplots, for example). Using this code
fig, graph = plt.subplots(figsize=(75,3))
sns.lineplot(x='YearBuilt',y='SalePrice',ax=graph,data=processed_data,color='red')
graph2 = graph.twinx()
sns.lineplot(x='YearBuilt', y='AvgOverallQual',ax=graph2,data=processed_data,color='teal')
I obtain this
But when I try to use different kinds, like this:
fig, graph = plt.subplots(figsize=(75,3))
sns.barplot(x='YearBuilt',y='SalePrice',ax=graph,data=processed_data,color='red')
graph2 = graph.twinx()
sns.lineplot(x='YearBuilt', y='AvgOverallQual',ax=graph2,data=processed_data,color='teal')
my graph looks like:
How do I overlay different kinds of graph in Seaborn?
A seaborn barplot is a categorical plot. The first bar will be at position 0, the second at position 1 etc. A lineplot is a numeric plot; it will put all points at a position given by the numeric coordinates.
Here, it seems there is no need to use seaborn at all. Since matplotlib bar plots are numerical as well, doing this in matplotlib alone will give you the desired overlay
fig, ax = plt.subplots(figsize=(75,3))
ax.bar('YearBuilt','SalePrice', data=processed_data, color='red')
ax2 = ax.twinx()
ax2.plot('YearBuilt', 'AvgOverallQual', data=processed_data, color='teal')

Plotting multiple scattter plots in the same graph instead of Facet Grids

Currently I have a few plots using Facet Grids in seaborn. I have the following code:
g = sns.FacetGrid(masterdata1,col = "courseName")
g=g.map(plt.scatter, "SubjectwisePercentage", "SemesterPercentage")
The above code plots subjectwisepercentage vs semesterpercentage, for different courses across a semester. How can I plot the different scatter plots in a single plot, instead of multiple plots across the facet grid? In the single plot, the plotted points for each course should be a different color.
There are links online that specify how to plot different datasets in a single plot. However I need to use the same dataset. Therefore I need to specify col="courseName", or something equivalent, to plot course wise data in a single plot. I am not sure of how to accomplish this. Thank you in advance for your help.
You can try using seaborn's scatter plot features. It allows to define, x, y, hue and style, and even size. Which gives up to a 5D view of your data. Sometimes, people like to make hue and style based on the same variables for better-looking graphs.
Sample code (not pretty much mine, since the seaborn documentation pretty much explains everything).
import seaborn as sns
import matplotlib.pyplot as plt
sns.set(style="ticks", color_codes=True)
tips = sns.load_dataset("tips")
# g = sns.FacetGrid(tips, col="sex", hue="time", palette="Set1",
# hue_order=["Dinner", "Lunch"])
# g= (g.map(plt.scatter, "total_bill", "tip")).add_legend()
# sns.scatterplot(data=tips, x="total_bill", y="tip", hue='time', style='sex')
sns.scatterplot(data=tips, x="total_bill", y="tip", hue='time', style='sex', size='size')
plt.show()
The matplotlib scatter plot can also be helpful. Since you can plot several data on the same plot with different markers/colors/sizes.
See this example.

Categories