代码之家  ›  专栏  ›  技术社区  ›  alpelito7

散点图未在matplotlib中正确调整打印范围

  •  1
  • alpelito7  · 技术社区  · 6 年前

    我正在绘制两个高斯数(一个以0为中心,另一个以100为中心),用 plt.plot plt.scatter 在里面 matplotlib 版本2.2.3。无论出于何种原因,子地块不会自动调整曲线中第二条曲线的绘图范围 scatter 情节

    当然,我可以手动操作——在这个简单的例子中——但实际上我有一个大的网格,我不想一个接一个地设置范围。

    这是怎么回事?有办法解决吗?

    这是我的代码:

    import numpy as np
    import matplotlib.pyplot as plt
    
    mu1, sigma1 = 0, 1
    x1 = mu1 + sigma1 * np.random.randn(10000)
    hist1, bins1 = np.histogram(x1, bins='auto', density=True)
    center1 = (bins1[:-1] + bins1[1:]) / 2
    
    mu2, sigma2 = 100, 15
    x2 = mu2 + sigma2 * np.random.randn(10000)
    hist2, bins2 = np.histogram(x2, bins='auto', density=True)
    center2 = (bins2[:-1] + bins2[1:]) / 2
    
    plt.subplot(2, 2, 1)
    plt.plot(center1, hist1)
    plt.text(2, 0.27, 'plot\n$\\mu$ = 0 \n$\\sigma$ = 1')
    plt.subplot(2, 2, 2)
    plt.scatter(center1, hist1)
    plt.text(2, 0.27, 'scatter\n$\\mu$ = 0 \n$\\sigma$ = 1')
    plt.subplot(2, 2, 3)
    plt.plot(center2, hist2)
    plt.text(127, 0.02, 'plot\n$\\mu$ = 100 \n$\\sigma$ = 15')
    plt.subplot(2, 2, 4)
    plt.scatter(center2, hist2)
    plt.text(127, 0.02, 'scatter\n$\\mu$ = 100 \n$\\sigma$ = 15')
    
    plt.show()
    

    所以结果是: grid_gaussians

    如果有人能帮上忙我会很高兴的,提前谢谢。如有任何回复或评论,将不胜感激。

    0 回复  |  直到 6 年前
        1
  •  2
  •   ImportanceOfBeingErnest    6 年前

    集合的自动缩放(分散)会产生 PathCollection )仍然是一个 unsolved problem ,尽管有一些解决办法正在讨论中。

    在上面的例子中,一个奇怪的黑客解决方案是添加一个空的情节, plt.plot() 在创建散布之前,将其移动到轴。

    import numpy as np
    import matplotlib.pyplot as plt
    
    mu1, sigma1 = 0, 1
    x1 = mu1 + sigma1 * np.random.randn(10000)
    hist1, bins1 = np.histogram(x1, bins='auto', density=True)
    center1 = (bins1[:-1] + bins1[1:]) / 2
    
    mu2, sigma2 = 100, 15
    x2 = mu2 + sigma2 * np.random.randn(10000)
    hist2, bins2 = np.histogram(x2, bins='auto', density=True)
    center2 = (bins2[:-1] + bins2[1:]) / 2
    
    
    plt.subplot(2, 2, 1)
    plt.plot(center1, hist1)
    plt.text(2, 0.27, 'plot\n$\\mu$ = 0 \n$\\sigma$ = 1')
    plt.subplot(2, 2, 2)
    plt.plot()                      ## <== empty plot
    plt.scatter(center1, hist1)
    plt.text(2, 0.27, 'scatter\n$\\mu$ = 0 \n$\\sigma$ = 1')
    plt.subplot(2, 2, 3)
    plt.plot(center2, hist2)
    plt.text(127, 0.02, 'plot\n$\\mu$ = 100 \n$\\sigma$ = 15')
    plt.subplot(2, 2, 4)
    plt.plot()                      ## <== empty plot
    plt.scatter(center2, hist2)
    plt.text(127, 0.02, 'scatter\n$\\mu$ = 100 \n$\\sigma$ = 15')
    
    plt.show()
    

    enter image description here

    以上更像是一个笑话,尽管它适用于这种特殊情况。一个更严肃的解决方案是创建实际数据的绘图,然后直接将其删除。这足以让自动缩放在散射的数据范围内按预期工作。

    import numpy as np
    import matplotlib.pyplot as plt
    
    mu1, sigma1 = 0, 1
    x1 = mu1 + sigma1 * np.random.randn(10000)
    hist1, bins1 = np.histogram(x1, bins='auto', density=True)
    center1 = (bins1[:-1] + bins1[1:]) / 2
    
    mu2, sigma2 = 100, 15
    x2 = mu2 + sigma2 * np.random.randn(10000)
    hist2, bins2 = np.histogram(x2, bins='auto', density=True)
    center2 = (bins2[:-1] + bins2[1:]) / 2
    
    
    plt.subplot(2, 2, 1)
    plt.plot(center1, hist1)
    plt.text(2, 0.27, 'plot\n$\\mu$ = 0 \n$\\sigma$ = 1')
    plt.subplot(2, 2, 2)
    sentinel, = plt.plot(center1, hist1)            ## <== sentinel plot
    sentinel.remove()
    plt.scatter(center1, hist1)
    plt.text(2, 0.27, 'scatter\n$\\mu$ = 0 \n$\\sigma$ = 1')
    plt.subplot(2, 2, 3)
    plt.plot(center2, hist2)
    plt.text(127, 0.02, 'plot\n$\\mu$ = 100 \n$\\sigma$ = 15')
    plt.subplot(2, 2, 4)
    sentinel, = plt.plot(center2, hist2)            ## <== sentinel plot
    sentinel.remove()
    plt.scatter(center2, hist2)
    plt.text(127, 0.02, 'scatter\n$\\mu$ = 100 \n$\\sigma$ = 15')
    
    
    plt.show()
    

    enter image description here

    最后,考虑一下,在一个大的绘图网格的情况下,您目前需要手动调整文本的位置。所以这里真正的解决方案是创建一个函数,为每个轴调用,让它自动完成所有事情。

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.offsetbox import AnchoredText
    
    def plot_my_hist(mu, sigma, ax=None):
        ax = ax or plt.gca()
        x = mu + sigma * np.random.randn(10000)
        hist, bins = np.histogram(x, bins='auto', density=True)
        center = (bins[:-1] + bins[1:]) / 2
        # Plot
        sentinel, = ax.plot(center, hist)      ## <== sentinel plot
        sentinel.remove()
        ax.scatter(center, hist)
        # Annotation
        at = AnchoredText(f'scatter\n$\\mu$ = {mu} \n$\\sigma$ = {sigma}',
                          loc='upper right')
        ax.add_artist(at)
    
    mus = [0, 0, 12, 12, 100, 100]
    sigmas = [1, 15, 1, 15, 1, 15]
    fig, axes = plt.subplots(ncols=3, nrows=2, figsize=(10,6))
    
    for ax, mu, sigma in zip(axes.T.flat, mus, sigmas):
        plot_my_hist(mu, sigma, ax=ax)
    
    
    fig.tight_layout()
    plt.show()
    

    enter image description here

        2
  •  1
  •   SpghttCd    6 年前

    好吧,老实说:我不知道。我唯一能发现的是,所描述的问题似乎始于最大值低于0.1的图。(即,简单地尝试一下 plt.scatter(center1, hist1/10) plt.scatter(center2, hist2*10) )

    然而,从你的例子中,我并不真正理解 scatter 在这里
    如果你喜欢自动缩放 plot 还有蓝色的圆圈——为什么不呢

    plt.plot(center2, hist2, 'o')
    

    ...?