Multiple marginal plots with Seaborn jointgrid plot - matplotlib

I'd like to draw a jointgrid plot with multiple marginal plots like below:
The reference code is:
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
penguins = sns.load_dataset("penguins")
print(penguins['species'])
plt.figure(figsize=(12,10))
g = sns.JointGrid(data=penguins, x="bill_length_mm", y="bill_depth_mm", hue="species")
g.plot_joint(sns.scatterplot)
g.plot_marginals(sns.boxplot)
plt.show()

If you want stripplot plots on the marginal axes, you could just add the hue parameter:
g = sns.JointGrid(data=penguins, x="bill_length_mm", y="bill_depth_mm", hue="species")
g.plot_joint(sns.scatterplot)
g.plot_marginals(sns.stripplot, hue="species", dodge=True)
But boxplot does not currently handle hue with only one coordinate variable assigned, so you need to draw each marginal plot separately:
g = sns.JointGrid(data=penguins, x="bill_length_mm", y="bill_depth_mm", hue="species")
g.plot_joint(sns.scatterplot)
sns.boxplot(penguins, x=g.hue, y=g.y, ax=g.ax_marg_y)
sns.boxplot(penguins, y=g.hue, x=g.x, ax=g.ax_marg_x)

Related

Is there a way to draw shapes on a python pandas plot

I am creating shot plots for NHL games and I have succeeded in making the plot, but I would like to draw the lines that you see on a hockey rink on it. I basically just want to draw two circles and two lines on the plot like this.
Let me know if this is possible/how I could do it
Pandas plot is in fact matplotlib plot, you can assign it to variable and modify it according to your needs ( add horizontal and vertical lines or shapes, text, etc)
# plot your data, but instead diplaying it assing Figure and Axis to variables
fig, ax = df.plot()
ax.vlines(x, ymin, ymax, colors='k', linestyles='solid') # adjust to your needs
plt.show()
working code sample
import pandas as pd
import matplotlib.pyplot as plt
import seaborn
from matplotlib.patches import Circle
from matplotlib.collections import PatchCollection
df = seaborn.load_dataset('tips')
ax = df.plot.scatter(x='total_bill', y='tip')
ax.vlines(x=40, ymin=0, ymax=20, colors='red')
patches = [Circle((50,10), radius=3)]
collection = PatchCollection(patches, alpha=0.4)
ax.add_collection(collection)
plt.show()

python pandas plot line chart in pandas.plot hbar

I have a horizontal bar chart created with
df.plot(kind='barh', ax=ax)
and now I would like to plot a horizontal line chart in the same axis. How can I do that. There seems to be no equivalent lineh
I tried to just flip axes when plotting a regular line
df=pd.DataFrame(dict(k=['A','B','C','D'], v=[1,3,2,3]))
df.plot(x='v', y='k')
but then pandas complains that there is no numerical data to plot
If you want to use matplotlib, you can do like the following. Here the command xticks() is to set x-tick labels only at integer values.
import pandas as pd
import matplotlib.pyplot as plt
df=pd.DataFrame(dict(k=['A','B','C','D'], v=[1,3,2,3]))
plt.plot(df.v, df.k)
plt.xticks(range(1, max(df.v)+1))
plt.show()

customize the color of bar chart while reading from two different data frame in seaborn

I have plotted a bar chart using the code below:
dffinal['CI-noCI']='Cognitive Impairement'
nocidffinal['CI-noCI']='Non Cognitive Impairement'
res=pd.concat([dffinal,nocidffinal])
sns.barplot(x='6month',y='final-formula',data=res,hue='CI-noCI')
plt.xticks(fontsize=8, rotation=45)
plt.show()
the result is as below:
I want to change the color of them to red and green.
How can I do?
just as information, this plot is reading two different data frame.
the links I have gone through were with the case the dataframe was only one data frame so did not apply to my case.
Thanks :)
You can use matplotlib to overwrite Seaborn's default color cycling to ensure the hues it uses are red and green.
import matplotlib.pyplot as plt
plt.rcParams['axes.prop_cycle'] = ("cycler('color', 'rg')")
Example:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
df = pd.DataFrame({'date': [1,2,3,4,4,5],
'value': [10,15,35,14,18,4],
'hue_v': [1,1,2,1,2,2]})
# The normal seaborn coloring is blue and orange
sns.barplot(x='date', y='value', data=df, hue='hue_v')
# Now change the color cycling and re-make the same plot:
plt.rcParams['axes.prop_cycle'] = ("cycler('color', 'rg')")
sns.barplot(x='date', y='value', data=df, hue='hue_v')
This will now impact all of the other figures you make, so if you want to restore the seaborn defaults for all other plots you need to then do:
sns.reset_orig()

how to draw axes passing through the origin in a 3D plot using matplotlib

I want to create a 3d plot like the following, such that axes pass through the origin with ticks on them.
PS: I could do that for 2D plots using matplotlib (the following figure). I searched a lot to do the same for 3D plots but I did not find any info.
If you want to restrict yourself to just matplotlib then we can use quiver3d plot as shown below. But the results may not be very visually appealing. You can see here how to add 3D text annotations.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
ax.set_xlim(0,2)
ax.set_ylim(0,2)
ax.set_zlim(0,2)
ax.view_init(elev=20., azim=32)
# Make a 3D quiver plot
x, y, z = np.zeros((3,3))
u, v, w = np.array([[1,1,0],[1,0,1],[0,1,1]])
ax.quiver(x,y,z,u,v,w,arrow_length_ratio=0.1)
plt.show()

Setting different axis range for seaborn PairGrid

I am plotting using seaborn and I am using seaborn.PairGrid function. This is creating 6 x 6 grid, where diagonal plots are histograms and off diagonal plots are scatter plots. Now I want to have different y ranges for each row of plots and different x ranges for each column of the plots. I searched stack exchange a lot but could not find a way to achieve this. Matplot version is 2.0.0 and seaborn version is 0.7.1.
Thanks
You can use the Axes.set_xlim() and Axes.set_ylim() methods on the axes of the seaborn PairGrid or FacetGrid. The axes are available from the PairGrid as .axes attribute.
import matplotlib.pyplot as plt
import seaborn as sns
iris = sns.load_dataset("iris")
g = sns.PairGrid(iris)
g = g.map_diag(plt.hist, edgecolor="k")
g = g.map_offdiag(plt.scatter, s=10)
g.axes[2,0].set_ylim(-10,10)
g.axes[0,1].set_xlim(-40,10)
plt.show()