繁体   English   中英

Pyplot - 根据 y 轴值显示 x 轴标签

[英]Pyplot - show x-axis labels according to y-axis value

我有 23.813 FPS 的 1 分钟 20 秒长视频记录。 更准确地说,我有 1923 帧,其中我一直在扫描所需的特征。 我通过神经网络检测到了一些特定的行为,并使用选定的指标为每一帧计算了一个值。

所以,现在,我有 XY 值来绘制图形:

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 来回答这个问题。 这将使事情更容易解释,并且可以很容易地推广到熊猫。

我假设您有以下两个数据数组:

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

通过计算差异可以轻松消除连续的峰值。 在掩码改变意义的位置,布尔掩码的差异将为True 然后,您将不得不采用其他所有元素来获取它从FalseTrue 以下代码将捕获从峰值开始或在峰值中间结束的所有极端情况:

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现在是xy的数组索引,表示每次峰值运行的第一个元素。 您可以通过交换if-else语句中的索引[1::2][::2]来获取最后一个元素,并在两种情况下都删除+ 1

标签的位置现在只是x[d]

第 2 部分:定位和格式化标签

对于这部分,您需要通过您正在绘图的Axes对象访问 Matplotlib 的面向对象的 API。 您已经在 Pandas 形式中拥有了它,从而使传输变得容易。 这是原始 Matplotlib 中的示例:

fig, axes = plt.subplots()
axes.plot(x, y)

现在使用股票代码 API轻松设置位置和标签。 您实际上直接设置了位置(而不是使用Locator ),因为您有一个非常固定的刻度列表:

axes.set_xticks(x[d])
axes.xaxis.set_major_formatter(ticker.StrMethodFormatter('{x:0.01g}s'))

对于此处显示的示例数据,您将获得

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM