如何在seaborn stripplot中设置抖动种子? [英] How to set seed for jitter in seaborn stripplot?

查看:63
本文介绍了如何在seaborn stripplot中设置抖动种子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试准确地复制带状图,以便我可以可靠地绘制线条并在其上书写.但是,当我生成带有抖动的带状图时,抖动是随机的,会阻止我实现目标.

我盲目地尝试了一些在其他 Stack Overflow 帖子中发现的 rcParams,例如 mpl.rcParams['svg.hashsalt'] 没有奏效.我也尝试为 random.seed() 设置种子但没有成功.

我正在运行的代码如下所示.

导入 seaborn 为 sns导入 matplotlib.pyplot 作为 plt随机导入plt.figure(figsize=(14,9))随机种子(123)类别 = []值 = []对于范围内的 i (0,200):n = random.randint(1,3)目录.append(n)对于范围内的 i (0,200):n = random.randint(1,100)values.append(n)sns.stripplot(类别,值,大小= 5)plt.title('随机抖动')plt.xticks([0,1,2],[1,2,3])plt.show()

此代码生成一个 stripplot 就像我想要的那样.但是,如果您运行代码两次,由于抖动,您将获得不同的点位置.我制作的图表需要抖动才能看起来不荒谬,但我想在图表上写字.然而,在运行代码之前无法知道点的确切位置,然后每次运行代码都会改变.

有什么方法可以为 seaborn stripplots 中的抖动设置种子,使其完美重现?

解决方案

  • 抖动由

    仅使用 random

    • 情节点四处移动

    将 seaborn 导入为 sns导入 matplotlib.pyplot 作为 plt随机导入图,轴 = plt.subplots(2, 3, figsize=(12, 12))对于范围内的 x(6):随机种子(123)类别 = []值 = []对于范围内的 i (0,200):n = random.randint(1,3)目录.append(n)对于范围内的 i (0,200):n = random.randint(1,100)values.append(n)行 = x//3列 = x % 3axcurr = 轴[行,列]sns.stripplot(类别,值,大小= 5,ax=axcurr)axcurr.set_title(f'随机抖动{x+1}')plt.show()

    使用 random 作为数据,np.random.seed 作为绘图

    fig, axes = plt.subplots(2, 3, figsize=(12, 12))对于范围内的 x(6):随机种子(123)类别 = []值 = []对于范围内的 i (0,200):n = random.randint(1,3)目录.append(n)对于范围内的 i (0,200):n = random.randint(1,100)values.append(n)行 = x//3列 = x % 3axcurr = 轴[行,列]np.random.seed(123)sns.stripplot(类别,值,大小= 5,ax=axcurr)axcurr.set_title(f'np.random jitter {x+1}')plt.show()

    I am trying to reproduce stripplots exactly so that I can draw lines and write on them reliably. However, when I produce a stripplot with jitter the jitter is random and prevents me from achieving my goal.

    I have blindly tried some rcParams I found in other Stack Overflow posts, such as mpl.rcParams['svg.hashsalt'] which hasn't worked. I also tried setting a seed for random.seed() without success.

    The code I am running looks like the following.

    import seaborn as sns
    import matplotlib.pyplot as plt
    import random
    
    plt.figure(figsize=(14,9))
    
    random.seed(123)
    
    catagories = []
    values = []
    
    for i in range(0,200):
        n = random.randint(1,3)
        catagories.append(n)
    
    for i in range(0,200):
        n = random.randint(1,100)
        values.append(n)
    
    sns.stripplot(catagories, values, size=5)
    plt.title('Random Jitter')
    plt.xticks([0,1,2],[1,2,3])
    plt.show()
    

    This code generates a stripplot just like I want. But if you run the code twice you will get different placements for the points, due to the jitter. The graph I am making requires jitter to not look ridiculous, but I want to write on the graph. However there is no way to know the exact positions of the points before running the code, which then changes every time the code is run.

    Is there any way to set a seed for the jitter in seaborn stripplots to make them perfectly reproduceable?

    解决方案

    • jitter is determined by scipy.stats.uniform
    • uniform is class uniform_gen(scipy.stats._distn_infrastructure.rv_continuous)
    • Which is a subclass of class rv_continuous(rv_generic)
    • Which has a seed parameter, and uses np.random
    • Therefore, use np.random.seed()
      • It needs to be called before each plot. In the case of the example, np.random.seed(123) must be inside the loop.

    from the Stripplot docstring

    jitter : float, ``True``/``1`` is special-cased, optional
        Amount of jitter (only along the categorical axis) to apply. This
        can be useful when you have many points and they overlap, so that
        it is easier to see the distribution. You can specify the amount
        of jitter (half the width of the uniform random variable support),
        or just use ``True`` for a good default.
    

    From class _StripPlotter in categorical.py

    • jitter is calculated with scipy.stats.uniform

    from scipy import stats
    
    class _StripPlotter(_CategoricalScatterPlotter):
        """1-d scatterplot with categorical organization."""
        def __init__(self, x, y, hue, data, order, hue_order,
                     jitter, dodge, orient, color, palette):
            """Initialize the plotter."""
            self.establish_variables(x, y, hue, data, orient, order, hue_order)
            self.establish_colors(color, palette, 1)
    
            # Set object attributes
            self.dodge = dodge
            self.width = .8
    
            if jitter == 1:  # Use a good default for `jitter = True`
                jlim = 0.1
            else:
                jlim = float(jitter)
            if self.hue_names is not None and dodge:
                jlim /= len(self.hue_names)
            self.jitterer = stats.uniform(-jlim, jlim * 2).rvs
    

    from the rv_continuous docstring

        seed : {None, int, `~np.random.RandomState`, `~np.random.Generator`}, optional
            This parameter defines the object to use for drawing random variates.
            If `seed` is `None` the `~np.random.RandomState` singleton is used.
            If `seed` is an int, a new ``RandomState`` instance is used, seeded
            with seed.
            If `seed` is already a ``RandomState`` or ``Generator`` instance,
            then that object is used.
            Default is None.
    

    Using your code with np.random.seed

    • All the plot points are the same

    import seaborn as sns
    import matplotlib.pyplot as plt
    import numpy as np
    
    fig, axes = plt.subplots(2, 3, figsize=(12, 12))
    for x in range(6):
    
        np.random.seed(123)
    
        catagories = []
        values = []
    
        for i in range(0,200):
            n = np.random.randint(1,3)
            catagories.append(n)
    
        for i in range(0,200):
            n = np.random.randint(1,100)
            values.append(n)
    
        row = x // 3
        col = x % 3
        axcurr = axes[row, col]
    
        sns.stripplot(catagories, values, size=5, ax=axcurr)
        axcurr.set_title(f'np.random jitter {x+1}')
    plt.show()
    

    using just random

    • The plot points move around

    import seaborn as sns
    import matplotlib.pyplot as plt
    import random
    
    fig, axes = plt.subplots(2, 3, figsize=(12, 12))
    for x in range(6):
    
        random.seed(123)
    
        catagories = []
        values = []
    
        for i in range(0,200):
            n = random.randint(1,3)
            catagories.append(n)
    
        for i in range(0,200):
            n = random.randint(1,100)
            values.append(n)
    
        row = x // 3
        col = x % 3
        axcurr = axes[row, col]
    
        sns.stripplot(catagories, values, size=5, ax=axcurr)
        axcurr.set_title(f'random jitter {x+1}')
    plt.show()
    

    Using random for the data and np.random.seed for the plot

    fig, axes = plt.subplots(2, 3, figsize=(12, 12))
    for x in range(6):
    
        random.seed(123)
    
        catagories = []
        values = []
    
        for i in range(0,200):
            n = random.randint(1,3)
            catagories.append(n)
    
        for i in range(0,200):
            n = random.randint(1,100)
            values.append(n)
    
        row = x // 3
        col = x % 3
        axcurr = axes[row, col]
    
        np.random.seed(123)
        sns.stripplot(catagories, values, size=5, ax=axcurr)
        axcurr.set_title(f'np.random jitter {x+1}')
    plt.show()
    

    这篇关于如何在seaborn stripplot中设置抖动种子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆