简体   繁体   English

Seaborn Distplot 下的不同阴影

[英]Different shading under Seaborn Distplot

I'm trying to create plot with shadings which are based on this MIC(1) line.我正在尝试使用基于此 MIC(1) 线的阴影创建绘图。 Different shading above than beneath.上面和下面不同的阴影。

from scipy import stats
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

def createSkewDist(mean, sd, skew, size):

    # calculate the degrees of freedom 1 required to obtain the specific skewness statistic, derived from simulations
    loglog_slope=-2.211897875506251 
    loglog_intercept=1.002555437670879 
    df2=500
    df1 = 10**(loglog_slope*np.log10(abs(skew)) + loglog_intercept)

    # sample from F distribution
    fsample = np.sort(stats.f(df1, df2).rvs(size=size))

    # adjust the variance by scaling the distance from each point to the distribution mean by a constant, derived from simulations
    k1_slope = 0.5670830069364579
    k1_intercept = -0.09239985798819927
    k2_slope = 0.5823114978219056
    k2_intercept = -0.11748300123471256

    scaling_slope = abs(skew)*k1_slope + k1_intercept
    scaling_intercept = abs(skew)*k2_slope + k2_intercept

    scale_factor = (sd - scaling_intercept)/scaling_slope    
    new_dist = (fsample - np.mean(fsample))*scale_factor + fsample

    # flip the distribution if specified skew is negative
    if skew < 0:
        new_dist = np.mean(new_dist) - new_dist

    # adjust the distribution mean to the specified value
    final_dist = new_dist + (mean - np.mean(new_dist))

    return final_dist



desired_mean = 30
desired_skew = 1.5
desired_sd = 20

final_dist = createSkewDist(mean=desired_mean, sd=desired_sd, skew=desired_skew, size=1000000)

# inspect the plots & moments, try random sample
fig, ax = plt.subplots(figsize=(12,7))
sns.distplot(final_dist, 
             hist=False, 
             ax=ax, 
             color='darkred', 
             kde_kws=dict(linewidth=4))

l1 = ax.lines[0]


# Get the xy data from the lines so that we can shade
x1 = l1.get_xydata()[:,0]
x1[0] = 0

y1 = l1.get_xydata()[:,1]
y1[0] = 0

ax.fill_between(x1,y1, color="lemonchiffon", alpha=0.3)


ax.set_ylim(0.0001,0.03)
ax.axhline(0.002, ls="--")
ax.set_xlim(1.5, 200)
ax.set_yticklabels([])
ax.set_xticklabels([])


trans = transforms.blended_transform_factory(
    ax.get_yticklabels()[0].get_transform(), ax.transData)

ax.text(0,0.0025, "{}".format("MIC(1) = 1"), color="blue", transform=trans, 
        ha="right", va="top", fontsize = 12)



trans_2 = transforms.blended_transform_factory(
    ax.get_xticklabels()[0].get_transform(), ax.transData)

ax.text(84,0, "{}".format("\n84"), color="darkred", transform=trans_2, 
        ha="center", va="top", fontsize = 12)

ax.text(1.5,0, "{}".format("\n0"), color="darkred", transform=trans_2, 
        ha="center", va="top", fontsize = 12)


ax.axvline(x = 84, ymin = 0, ymax = 0.03, ls = '--', color = 'darkred' )


ax.set_yticks([])
ax.set_xticks([])

ax.spines['top'].set_color(None)
ax.spines['right'].set_color(None)
ax.spines['left'].set_linewidth(2)
ax.spines['bottom'].set_linewidth(2)
ax.set_ylabel("Concentration [mg/L]", labelpad = 80, fontsize = 15)
ax.set_xlabel("Time [h]", labelpad = 80, fontsize = 15)
ax.set_title("AUC/MIC", fontsize = 20, pad = 30)


plt.annotate("AUC/MIC", 
             xy=(18, 0.02), 
             xytext=(18, 0.03), 
             arrowprops=dict(arrowstyle="->"), fontsize = 12);

;

That's what I have:这就是我所拥有的:

在此处输入图片说明

And that's what I'd like to have (it's done in paint, so forgive me :) ):这就是我想要的(它是用油漆完成的,所以请原谅我:)): 在此处输入图片说明

I was experimenting with fill_between and fill_betweenx.我正在试验fill_between 和fill_betweenx。 However, without any satisfying results.然而,没有任何令人满意的结果。 Definitely, run out of ideas.当然,没有想法了。 I'd really appreciate any help on this.我真的很感激这方面的任何帮助。 Best wishes!最好的祝愿!

Your fill_between works as expected.您的fill_between按预期工作。 The problem is that color="lemonchiffon" with alpha=0.3 is barely visible.问题是alpha=0.3 color="lemonchiffon"几乎不可见。 Try to use a brighter color and/or a higher value for alpha .尝试使用更亮的颜色和/或更高的alpha值。

So, this colors the part of the graph between zero and the kde curve.因此,这会为零和 kde 曲线之间的图形部分着色。

Now, to create a different coloring above and below the horizontal line, where= and np.minimum can be used in fill_between :现在,为了创建上面和水平线,以下不同的着色where=np.minimum可被用fill_between

pos_hline = 0.002
ax.fill_between(x1, pos_hline, y1, color="yellow", alpha=0.3, where=y1 > pos_hline)
ax.fill_between(x1, 0, np.minimum(y1, pos_hline), color="blue", alpha=0.3)

Without where=y1 > pos_hline , fill_between would also color the region above the curve where the curve falls below that horizontal line.如果没有where=y1 > pos_hlinefill_between也会为曲线上方的区域着色,其中曲线低于该水平线。

结果图

PS: Note that sns.histplot has been deprecated since Seaborn version 0.11 . PS:请注意,自 Seaborn 版本0.11以来, sns.histplot已被弃用。 To only plot the kde curve, you can use sns.kdeplot :要仅绘制 kde 曲线,您可以使用sns.kdeplot

sns.kdeplot(final_dist, ax=ax, color='darkred', linewidth=4)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM