我有 1 分 20 秒长、23.813 FPS 的视频记录。更准确地说,我有 1923 个帧,我在其中扫描了所需的特征。我通过神经网络检测到了一些特定行为,并使用所选指标计算了每个帧的值。
现在,我有 X-Y 值来绘制图表:
X: time (each step of size 0,041993869s)
Y: a value measured by neural network
在默认状态下,绘图如下所示:
因此,我尝试限制垃圾箱的数量,因为我相信这些垃圾箱将分布在我的所有值中。但他们不是。如您所见,仅呈现前十五个 x 值:
pyplot.locator_params(axis='x', nbins=15)
但两者都不是理想的状态。所需的状态应该渲染此类 x-bins 的标签,其 y 值高于例如1.2。所以,它应该看起来像这样:
有可能达到这样的结果吗?
代码:
# draw plot
from pandas import read_csv
from matplotlib import pyplot
test_video_fps = 23.813
df = read_csv('/path/to/csv/file/file.csv', header=None)
df.columns = ['anomaly']
df['time'] = [round((i + 1) / test_video_fps, 2) for i in range(df.shape[0])]
axes = df.plot.bar(x='time', y='anomaly', rot='0')
# pyplot.locator_params(axis='x', nbins=15)
# axes.get_xaxis().set_visible(False)
fig = pyplot.gcf()
fig.set_size_inches(16, 10)
fig.savefig('/path/to/output/plot.png', dpi=100)
# pyplot.show()
示例:
带有原始数据子集的简单示例。
0.379799
0.383786
0.345488
0.433286
0.469474
0.431993
0.474253
0.418843
0.491070
0.447778
0.384890
0.410994
0.898229
1.872756
2.907009
3.691382
4.685749
4.599612
3.738768
8.043357
7.660785
2.311198
1.956096
2.877326
3.467511
3.896339
4.250552
6.485533
7.452986
7.103761
2.684189
2.516134
1.512196
1.435303
0.852047
0.842551
0.957888
0.983085
0.990608
1.046679
1.082040
1.119655
0.962391
1.263255
1.371034
1.652812
2.160451
2.646674
1.460051
1.163745
0.938030
0.862976
0.734119
0.567076
0.417270
期望的情节:
最佳答案
你的问题已经变成了一个由两部分组成的问题,但它很有趣,所以我会回答这两部分。
我将用 Matplotlib 面向对象的表示法用 numpy 数据而不是 pandas 来回答这个问题。这将使事情更容易解释,并且可以轻松推广到 pandas。
我假设您有以下两个数据数组:
dt = 0.041993869
x = np.arange(0.0, 15 * dt, dt)
y = np.array([1., 1.1, 1.3, 7.6, 2.4, 0.8, 0.7, 0.8, 1.0, 1.5, 10.0, 4.5, 3.2, 0.9, 0.7])
第 1 部分:确定需要放置标签的位置
可以屏蔽数据以获得峰值的位置:
mask = y > 1.2
通过计算差异可以轻松消除连续峰值。 bool 掩码的 diff 在掩码改变意义的位置将为 True
。然后,您必须获取所有其他元素来获取它从 False
到 True
的位置。以下代码将捕获以峰值开始或以峰值中间结束的所有极端情况:
d = np.flatnonzero(np.diff(mask))
if mask[d[0]]: # First diff is end of peak: True to False
d = np.concatenate(([0], d[1::2] + 1))
else:
d = d[::2] + 1
d
现在是 x
和 y
的数组索引,表示每个峰的第一个元素。您可以通过交换 if-else
语句中的索引 [1::2]
和 [::2]
来获取最后一个元素,并在这两种情况下删除 + 1
。
标签的位置现在只是x[d]
。
第 2 部分:定位标签并设置其格式
对于这一部分,您将需要通过您正在绘制的 Axes
对象访问 Matplotlib 的面向对象 API。您已经以 pandas 形式获得了该文件,从而使传输变得容易。这是原始 Matplotlib 中的示例:
fig, axes = plt.subplots()
axes.plot(x, y)
现在使用ticker API轻松设置位置和标签。实际上,您可以直接设置位置(而不是使用 Locator
),因为您有一个非常固定的刻度列表:
axes.set_xticks(x[d])
axes.xaxis.set_major_formatter(ticker.StrMethodFormatter('{x:0.01g}s'))
对于此处显示的示例数据,您将得到
关于python - Pyplot - 根据 y 轴值显示 x 轴标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60047328/