Issue
I've created a raincloud plot using the following code:
#Rainplot
dx = 'Time Point'; dy = 'Score'; ort = "v"; pal = "Set2"; sigma = .2;
f, ax = plt.subplots(figsize=(7, 5))
pt.RainCloud(x = dx, y = dy, data = df, palette = pal, bw = sigma,
width_viol = .9, ax= ax, orient = ort, move = .2)
plt.title("")
plt.ylabel('Score', fontsize = 20)
plt.xlabel('', fontsize = 20)
plt.grid(color = 'w')
if savefigs:
plt.savefig('/Users/zeidanlab/Desktop/gv/rainplots/figure_tsc.png', bbox_inches='tight')
I'm wondering if there is a way to have the box plot overlap with the distribution blob.
Solution
Here is an approach to combine a half violinplot with a boxplot and a stripplot.
Half violins are created by extracting their bounding box, and using half of it to clip the violins.
The dots of the stripplot are moved in order not to overlap.
from matplotlib import pyplot as plt
import seaborn as sns
import numpy as np
sns.set_style('white')
tips = sns.load_dataset('tips')
palette = sns.cubehelix_palette(start=.5, rot=-.5, dark=0.3, light=0.7)
ax = sns.violinplot(y="day", x="total_bill", data=tips,
palette=palette,
scale="width", inner=None)
xlim = ax.get_xlim()
ylim = ax.get_ylim()
for violin in ax.collections:
bbox = violin.get_paths()[0].get_extents()
x0, y0, width, height = bbox.bounds
violin.set_clip_path(plt.Rectangle((x0, y0), width, height / 2, transform=ax.transData))
sns.boxplot(y="day", x="total_bill", data=tips, saturation=1, showfliers=False,
width=0.3, boxprops={'zorder': 3, 'facecolor': 'none'}, ax=ax)
old_len_collections = len(ax.collections)
sns.stripplot(y="day", x="total_bill", data=tips, color='dodgerblue', ax=ax)
for dots in ax.collections[old_len_collections:]:
dots.set_offsets(dots.get_offsets() + np.array([0, 0.12]))
ax.set_xlim(xlim)
ax.set_ylim(ylim)
plt.show()
Here is another example, in the vertical direction.
from matplotlib import pyplot as plt
import seaborn as sns
import numpy as np
sns.set_style('white')
iris = sns.load_dataset('iris')
palette = 'Set2'
ax = sns.violinplot(x="species", y="sepal_length", data=iris, hue="species", dodge=False,
palette=palette,
scale="width", inner=None)
xlim = ax.get_xlim()
ylim = ax.get_ylim()
for violin in ax.collections:
bbox = violin.get_paths()[0].get_extents()
x0, y0, width, height = bbox.bounds
violin.set_clip_path(plt.Rectangle((x0, y0), width / 2, height, transform=ax.transData))
sns.boxplot(x="species", y="sepal_length", data=iris, saturation=1, showfliers=False,
width=0.3, boxprops={'zorder': 3, 'facecolor': 'none'}, ax=ax)
old_len_collections = len(ax.collections)
sns.stripplot(x="species", y="sepal_length", data=iris, hue="species", palette=palette, dodge=False, ax=ax)
for dots in ax.collections[old_len_collections:]:
dots.set_offsets(dots.get_offsets() + np.array([0.12, 0]))
ax.set_xlim(xlim)
ax.set_ylim(ylim)
ax.legend_.remove()
plt.show()
Answered By - JohanC
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.