如何摆脱相对频率图后出现的垂直线? (Python 3.5)

How do I get rid of the vertical lines that appear after doing a relative frequency plot? (Python 3.5)

我目前正在尝试为某些资产(特别是股票)获得的对数 returns 构建一个相对频率图,其中我在 y 轴上使用了 log10 刻度 plt.yscale('log')。但是,我得到了一些垂直线,这些垂直线在我在 Python 上构建的图形的某些点处明显趋于无穷大,如下所示:

这显然不应该发生。相反,它应该如下图所示:

这显然与我的相似,只是它不包括那些点上的垂直线。我的代码如下:

plt.figure(1)
plt.figure(figsize=(9,7))
hist1, bins1 = np.histogram(returns_assetA_daily_mat, bins=20)
hist2, bins2 = np.histogram(returns_assetA_weekly_mat, bins=20)
hist3, bins3 = np.histogram(returns_assetA_monthly_mat, bins=20)
hist1 = hist1/len(returns_assetA_daily_mat)
hist2 = hist2/len(returns_assetA_weekly_mat)
hist3 = hist3/len(returns_assetA_monthly_mat)
bins1 = 0.5 * (bins1[1:] + bins1[:-1])
bins2 = 0.5 * (bins2[1:] + bins2[:-1])
bins3 = 0.5 * (bins3[1:] + bins3[:-1])
plt.plot(bins1, hist1, bins2, hist2, bins3, hist3)
plt.yscale('log')
plt.xlabel('Log-Returns')
plt.ylabel('Relative Frequency')
plt.title('Original for Asset A')
plt.show()

知道这一点很有用

returns_assetA_daily_mat, returns_assetA_weekly_mat, returns_assetA_monthly_mat

只是行数组,其中包含资产的每日、每周和每月对数 returns 值,其中也包含负值、正值和零,所以也许因为我在y 轴的负值或零可能是潜在问题的原因,因为显然随着 x 趋于零,对数将趋于负无穷大?也许问题出在我的代码结构中?如果这个问题没有解决方案,有没有什么办法可以隔离那些包含垂直线的点以趋向于负无穷大,从而使它们看起来像孤立点?我是一名 Python 新手,目前正在学习它作为我计算金融硕士学位的一部分,因此非常感谢任何形式的帮助!非常感谢!

在 Matplotlib 中,在绘图中可视化 "remove" 点的一种方法是将受影响的点设置为 numpy.nan。这样做的效果是 numpy.nan 前后的点将显示一个差距,这就是我相信你所追求的。

因此,对于您的数组,在绘图之前找到任何负值或 0 并将它们设置为 numpy.nan。因为您正在计算直方图,所以它们永远不会产生负值,因此您实际上只是在检查等于 0 的 bin。

您需要确保的一件事是将数组的类型更改为 floatnumpy.nan 仅存在于浮点数组中。

如果您还想绘制它们中的每一个以添加图例,只需通过调用 matplotlib.pyplot.plot 三次在同一图形上一次绘制每个数组,然后添加您的图例,然后显示图:

plt.figure(1)
plt.figure(figsize=(9,7))
hist1, bins1 = np.histogram(returns_assetA_daily_mat, bins=20)
hist2, bins2 = np.histogram(returns_assetA_weekly_mat, bins=20)
hist3, bins3 = np.histogram(returns_assetA_monthly_mat, bins=20)
hist1 = hist1/len(returns_assetA_daily_mat)
hist2 = hist2/len(returns_assetA_weekly_mat)
hist3 = hist3/len(returns_assetA_monthly_mat)
bins1 = 0.5 * (bins1[1:] + bins1[:-1])
bins2 = 0.5 * (bins2[1:] + bins2[:-1])
bins3 = 0.5 * (bins3[1:] + bins3[:-1])

# New code
hist1_new = hist1.astype(np.float)
hist2_new = hist2.astype(np.float)
hist3_new = hist3.astype(np.float)
hist1_new[hist1 <= 0] = np.nan
hist2_new[hist2 <= 0] = np.nan
hist3_new[hist3 <= 0] = np.nan

# New - Plot the three graphs separately for making the legend
# Also plot the NaN versions
plt.plot(bins1, hist1_new, label='Daily')
plt.plot(bins2, hist2_new, label='Weekly')
plt.plot(bins3, hist3_new, label='Monthly')

plt.yscale('log')
plt.xlabel('Log-Returns')
plt.ylabel('Relative Frequency')
plt.title('Original for Asset A')
plt.legend() # Added for the legend
plt.show()

我没有你的数据,但我可以给你看一个这个工作的玩具示例:

# Import relevant packages
import numpy as np
import matplotlib.pyplot as plt

# Create array from 0 to 8 for the horizontal axis
x = np.arange(9)

# Create test array with some zero, positive and negative values
y = np.array([1, 2, 3, 0, -1, -2, 1, 2, -1])

# Create a figure with two graphs in one row
plt.subplot(1, 2, 1)

# Graph the data normally
plt.plot(x, y)

# Visually remove those points that are zero or negative
y2 = y.astype(np.float)
y2[y2 <= 0] = np.nan

# Plot these points now
plt.subplot(1, 2, 2)
plt.plot(x, y2)

# Adjust the x and y limits (see further discussion below)
plt.xlim(0, 8)
plt.ylim(-1, 3)

# Show the figure
plt.show()

请注意,我强制执行的第二个图 xy 限制与第一个图相同,因为我们在视觉上删除了点,因此轴会自动调整。我们得到: