gpt4 book ai didi

python - 拟合 Von Mises 分布的圆形直方图

转载 作者:行者123 更新时间:2023-12-04 11:32:40 26 4
gpt4 key购买 nike

在过去的几天里,我一直在尝试使用 python 绘制圆形数据,方法是构建一个范围从 0 到 2pi 的圆形直方图并拟合 Von Mises 分布。我真正想要实现的是:

  • 具有拟合 Von-Mises 分布的方向数据。该图是使用 Matplotlib、Scipy 和 Numpy 构建的,可以在以下位置找到:http://jpktd.blogspot.com/2012/11/polar-histogram.html

  • enter image description here
  • 该图是使用 R 生成的,但给出了我想要绘制的内容的想法。可以在这里找到:https://www.zeileis.org/news/circtree/

  • enter image description here
    到目前为止我做了什么:
    from scipy.special import i0  
    import numpy as np
    import matplotlib.pyploy as plt

    # From my data I fitted a Von-Mises distribution, calculating Mu and Kappa.
    mu = -0.343
    kappa = 10.432

    # Construct random Von-Mises distribution based on Mu and Kappa values
    r = np.random.vonmises(mu, kappa, 1000)

    # Adjust Von-Mises curve from fitted data
    x = np.linspace(-np.pi, np.pi, num=501)
    y = np.exp(kappa*np.cos(x-mu))/(2*np.pi*i0(kappa))

    # Adjuste x limits and labels
    plt.xlim(-np.pi, np.pi)
    plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
    labels=[r'$-\pi$ (0º)', r'$-\frac{\pi}{2}$ (90º)', '0 (180º)', r'$\frac{\pi}{2}$ (270º)', r'$\pi$'])

    # Plot adjusted Von-Mises function as line
    plt.plot(x, y, linewidth=2, color='red', zorder=3

    # Plot distribution
    plt.hist(r, density=True, bins=20, alpha=1, edgecolor='white');
    plt.title('Slaty Cleavage Strike', fontweight='bold', fontsize=14)
    enter image description here
    我尝试绘制圆形直方图 基于诸如 Circular / polar histogram in python 之类的问题
    # From the data above (mu, kappa, x and y):

    theta = np.linspace(-np.pi, np.pi, num=50, endpoint=False)
    radii = np.exp(kappa*np.cos(theta-mu))/(2*np.pi*i0(kappa))

    # Bin width?
    width = (2*np.pi) / 50

    # Construct ax with polar projection
    ax = plt.subplot(111, polar=True)

    # Set Zero to North
    ax.set_theta_zero_location('N')
    ax.set_theta_direction(-1)

    # Plot bars:
    bars = ax.bar(x = theta, height = radii, width=width)
    # Plot Line:
    line = ax.plot(x, y, linewidth=1, color='red', zorder=3)

    # Grid settings
    ax.set_rgrids(np.arange(1, 1.6, 0.5), angle=0, weight= 'black');
    enter image description here
    备注:
  • 我的圆形直方图在错误的方向绘制了我的数据,相差 180 度:比较两个直方图。 见编辑 1
  • 我相信这可能与定义在 [-pi,pi] https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.vonmises.html 上的 scipy.stats.vonmises 有关。 见编辑 1
  • 我的数据最初在 [0,2pi] 之间变化。我转换为 [-pi,pi] 以拟合 Von Mises 并计算 Mu 和 Kappa。 见编辑 1

  • 我真的很想将我的数据绘制为第一个图。我的数据是地质定向数据(方位角)。有人有什么想法吗?
    附注。抱歉,帖子太长了。我希望这至少有帮助
    编辑 1:
    通过评论,我意识到有些人对数据是否从 [0,2pi] 开始感到困惑。或 [-pi,pi] .我意识到我的圆形直方图中绘制的错误方向来自以下内容:
  • 我的原始数据(地质数据)范围在 [0,2pi] 之间,即 0 到 360 度;
  • 但是,scipy.stats.vonmises 在 [-pi, pi] 中计算概率密度函数;
  • 我从我的数据中减去 pi,以便使用 scipy.stats.vonmises my_data - pi ;
  • 曾经MuKappa计算(正确),我添加了 piMu值(value),恢复原来的方向,现在再次介于[0,2pi]之间.
  • 现在,我的数据正确地指向东南:

  • enter image description here
    # Add pi to fitted Mu. 
    mu = - 0.343 + np.pi
    kappa = 10.432

    x = np.linspace(-np.pi, np.pi, num=501)
    y = np.exp(kappa*np.cos(x-mu))/(2*np.pi*i0(kappa))

    theta = np.linspace(-np.pi, np.pi, num=50, endpoint=False)
    radii = np.exp(kappa*np.cos(theta-mu))/(2*np.pi*i0(kappa))

    # Bin width?
    width = (2*np.pi) / 50

    ax = plt.subplot(111, polar=True)

    # Angles increase clockwise from North
    ax.set_theta_zero_location('N')
    ax.set_theta_direction(-1)

    bars = ax.bar(x = theta, height = radii, width=width)

    line = ax.plot(x, y, linewidth=1, color='red', zorder=3)

    ax.set_rgrids(np.arange(1, 1.6, 0.5), angle=0, weight= 'black');
    编辑 2
    正如接受的答案的评论所建议的那样,技巧正在改变 y_lim , 如下:
    enter image description here
    # SE DIRECTION
    mu = - 0.343 + np.pi
    kappa = 10.432


    x = np.linspace(-np.pi, np.pi, num=501)
    y = np.exp(kappa*np.cos(x-mu))/(2*np.pi*i0(kappa))

    theta = np.linspace(-np.pi, np.pi, num=50, endpoint=False)
    radii = np.exp(kappa*np.cos(theta-mu))/(2*np.pi*i0(kappa))

    # PLOT
    plt.figure(figsize=(5,5))
    ax = plt.subplot(111, polar=True)

    # Bin width?
    width = (2*np.pi) / 50

    # Angles increase clockwise from North
    ax.set_theta_zero_location('N'); ax.set_theta_direction(-1);

    bars = ax.bar(x=theta, height = radii, width=width, bottom=0)

    # Plot Line
    line = ax.plot(x, y, linewidth=2, color='firebrick', zorder=3 )

    # 'Trick': This will display Zero as a circle. Fitted Von-Mises function will lie along zero.
    ax.set_ylim(-0.5, 1.5);

    ax.set_rgrids(np.arange(0, 1.6, 0.5), angle=60, weight= 'bold',
    labels=np.arange(0,1.6,0.5));
    最后说明:
  • 提供的直方图已经标准化,因此可以用相同比例的 vM 分布绘制。
  • 最佳答案

    这是我取得的成绩:
    enter image description here
    我不完全确定您是否希望 x 的范围为 [-pi,pi][0,2pi] .如果您想要范围 [0,2pi]相反,只需注释掉这些行 ax.set_xlimax.set_xticks .

    from scipy.special import i0
    import numpy as np
    import matplotlib.pyplot as plt


    # From my data I fitted a Von-Mises distribution, calculating Mu and Kappa.
    mu = -0.343
    kappa = 10.432

    # Construct random Von-Mises distribution based on Mu and Kappa values
    r = np.random.vonmises(mu, kappa, 1000)

    # Adjust Von-Mises curve from fitted data
    x = np.linspace(-np.pi, np.pi, num=501)
    y = np.exp(kappa*np.cos(x-mu))/(2*np.pi*i0(kappa))

    # Adjuste x limits and labels
    plt.xlim(-np.pi, np.pi)
    plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
    labels=[r'$-\pi$ (0º)', r'$-\frac{\pi}{2}$ (90º)', '0 (180º)', r'$\frac{\pi}{2}$ (270º)', r'$\pi$'])

    # Plot adjusted Von-Mises function as line
    plt.plot(x, y, linewidth=2, color='red', zorder=3)

    # Plot distribution
    plt.hist(r, density=True, bins=20, alpha=1, edgecolor='white')
    plt.title('Slaty Cleavage Strike', fontweight='bold', fontsize=14)



    # From the data above (mu, kappa, x and y):

    theta = np.linspace(-np.pi, np.pi, num=50, endpoint=False)
    radii = np.exp(kappa * np.cos(theta - mu)) / (2 * np.pi * i0(kappa))

    # Display width
    width = (2 * np.pi) / 50

    # Construct ax with polar projection
    ax = plt.subplot(111, polar=True)

    # Set Orientation
    ax.set_theta_zero_location('E')
    ax.set_theta_direction(-1)
    ax.set_xlim(-np.pi/1.000001, np.pi/1.000001) # workaround for a weird issue
    ax.set_xticks([-np.pi/1.000001 + i/8 * 2*np.pi/1.000001 for i in range(8)])

    # Plot bars:
    bars = ax.bar(x=theta, height=radii, width=width)
    # Plot Line:
    line = ax.plot(x, y, linewidth=1, color='red', zorder=3)

    # Grid settings
    ax.set_rgrids(np.arange(.5, 1.6, 0.5), angle=0, weight='black')


    plt.show()

    关于python - 拟合 Von Mises 分布的圆形直方图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67282865/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com