I search to draw a catplot with violin plots using seaborn with a broken y-axis ('cause I have a cause consequence process acting at two different scales: one between [0,0.2] and a second between [2,12] of my quantitative y-variable).
I understood from this answer that there is not implemented easy feature allowing this kind of plot in seaborn (yet?) So I tried different approaches, unsuccessful, to stack two plots of the same dataset but with two different scales.
Explored unsuccessful attempt :
Let's use the standard dataset 'exercise', I tried:
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
exercise = sns.load_dataset("exercise")
f, (ax1, ax2) = plt.subplots(ncols=2, nrows=1, sharey=True)
f = sns.catplot(x="time", y="pulse", hue="kind",data=exercise, kind="violin",ax=ax1)
f = sns.catplot(x="time", y="pulse", hue="kind",data=exercise, kind="violin",ax=ax2)
ax1.set_ylim(0, 6.5) # those limits are fake
ax2.set_ylim(13.5, 20)
plt.subplots_adjust(wspace=0, hspace=0)
plt.show()
I also tried to use facegrid but without success
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
exercise = sns.load_dataset("exercise")
g = sns.FacetGrid(exercise, col="kind",row="time")
g.map(sns.catplot, x="time", y="pulse", hue="kind",data=exercise, kind="violin")
plt.show()
here it gives me the right base of grid of plots but plots happen in other figures.
If you want to draw on a subplot, you cannot use catplot
, which is a figure-level function. Instead, you need to use violinplot
directly. Also, if you want two different y-scales, you cannot use sharey=True
when you create your subplots.
The rest is pretty much copied/pasted from matplotlib's broken axes tutorial
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
exercise = sns.load_dataset("exercise")
f, (ax_top, ax_bottom) = plt.subplots(ncols=1, nrows=2, sharex=True, gridspec_kw={'hspace':0.05})
sns.violinplot(x="time", y="pulse", hue="kind",data=exercise, ax=ax_top)
sns.violinplot(x="time", y="pulse", hue="kind",data=exercise, ax=ax_bottom)
ax_top.set_ylim(bottom=125) # those limits are fake
ax_bottom.set_ylim(0,100)
sns.despine(ax=ax_bottom)
sns.despine(ax=ax_top, bottom=True)
ax = ax_top
d = .015 # how big to make the diagonal lines in axes coordinates
# arguments to pass to plot, just so we don't keep repeating them
kwargs = dict(transform=ax.transAxes, color='k', clip_on=False)
ax.plot((-d, +d), (-d, +d), **kwargs) # top-left diagonal
ax2 = ax_bottom
kwargs.update(transform=ax2.transAxes) # switch to the bottom axes
ax2.plot((-d, +d), (1 - d, 1 + d), **kwargs) # bottom-left diagonal
#remove one of the legend
ax_bottom.legend_.remove()
plt.show()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.