matplotlib:当值出现时绘制特殊符号

时间:2013-01-26 23:42:15

标签: python graph matplotlib plot

使用matplotlib我想绘制一个延迟列表,以便:

    X轴上我在列表中有延迟的位置
  • Y轴我有延迟本身

现在,在我的列表中有一个特殊值'L',我希望它在X轴上作为红叉绘制。 p>

我最后怎么做?

1 个答案:

答案 0 :(得分:1)

有许多不同的方法可以做到这一点。

首先,让我们使您的数据成为一个numpy数组,以便我们可以使用布尔索引。这样可以更容易地从数据值中隔离“已标记”的"L"值。

理想情况下,您将事物转换为蒙版数组,其中“L”值被屏蔽(并且浮动到处,而不是混合数据类型)。但是为了简单起见,让我们在这里使用一个对象数组,以便混合字符串和浮点数。

import matplotlib.pyplot as plt
import numpy as np

delays = np.array([0.5, 2.3, 'L', 0.9, 'L', 2], dtype=object)
x = np.arange(delays.size)

fig, ax = plt.subplots()
ax.plot(x[delays != 'L'], delays[delays != 'L'], 'bo')

# Expand axis limits by 0.5 in all directions for easier viewing
limits = np.array(ax.axis())
ax.axis(limits + [-0.5, 0.5, -0.5, 0.5])

flag_positions = x[delays == 'L']
ax.plot(flag_positions, np.zeros_like(flag_positions), 'rx', 
        clip_on=False, mew=2)

plt.show()

enter image description here

然而,红色x位于固定的y位置,如果我们平移或缩放,它们将离开x轴。

您可以使用自定义转换解决此问题。在这种情况下,我们希望x坐标使用“正常”数据坐标(ax.transData)和y坐标来使用轴坐标系(例如0-1,其中0是底部,1是顶部:ax.transAxes)。为此,我们将使用BlendedGenericTransform,它使用两种不同的变换:一种用于x坐标,另一种用于y坐标。

因此,如果您希望红色x始终位于x轴上,而不管绘图是如何平移或缩放的,那么您可能会执行以下操作:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.transforms import BlendedGenericTransform

delays = np.array([0.5, 2.3, 'L', 0.9, 'L', 2], dtype=object)
x = np.arange(delays.size)

fig, ax = plt.subplots()
ax.plot(x[delays != 'L'], delays[delays != 'L'], 'bo')

flags = x[delays == 'L']
ax.plot(flags, np.zeros_like(flags), 'rx', clip_on=False, mew=2,
        transform=BlendedGenericTransform(ax.transData, ax.transAxes))

# Expand axis limits by 0.5 in all directions for easier viewing
limits = np.array(ax.axis())
ax.axis(limits + [-0.5, 0.5, -0.5, 0.5])

plt.show()

enter image description here

我们可以通过使用蒙版数组使事情变得更清晰(也可以查看pandas)。与使用具有混合字符串和浮点值的对象数组相比,使用掩码数组(或者,再次,pandas)是指示丢失数据的更好选项。举个例子:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.transforms import BlendedGenericTransform

delays = [0.5, 2.3, 'L', 0.9, 'L', 2]
delays = [item if item != 'L' else np.nan for item in delays]
delays = np.ma.masked_invalid(delays)

fig, ax = plt.subplots()

ax.plot(delays, 'bo')

flags = delays.mask.nonzero()
ax.plot(flags, np.zeros_like(flags), 'rx', clip_on=False, mew=2,
        transform=BlendedGenericTransform(ax.transData, ax.transAxes))

# Expand axis limits by 0.5 in all directions for easier viewing
limits = np.array(ax.axis())
ax.axis(limits + [-0.5, 0.5, -0.5, 0.5])

plt.show()