我想在笛卡尔图上绘制风向测量值,其中X轴为时间,Y轴为方向。因为当从359移动到0度时方向包裹,所以绘制连接359到0的线是不合适的。
如果较短的跳跃没有包裹,是否可以条件地绘制连接线?这是一系列带有连接线的值:
10-15-30-90-150-290-350 40-50-20 310-250-150
我假设我会使用类似下面的公式来确定A和B之间是否应该有一条线:
max(A,B) - min(A,B) <= 180
答案 0 :(得分:3)
在撰写问题时,我提出了一种工作方法:只需添加一个None
值即表示数据不连续且线条已断开。
为了使它完美,我在我的范围之外添加了点数,这样线条就会让图形位于顶部并从底部出来。
这是通过添加相关数据点的简单生成器完成的:
def break_degree_wrap(values):
values1, values2 = itertools.tee(values)
# Yield the first value
yield next(values2)
for (prev_datetime, prev_val), (datetime, val) in itertools.izip(values1, values2):
# If the data wraps over the top
if val > prev_val and val - prev_val > 180:
yield (datetime, val - 360)
yield (datetime, None)
yield (prev_datetime, prev_val + 360)
# If the data wraps under the bottom
elif val < prev_val and prev_val - val > 180:
yield (datetime, val + 360)
yield (datetime, None)
yield (prev_datetime, prev_val - 360)
# Add each original value
yield (datetime, val)
这可以很容易地推广到接受有效范围,而不是硬编码(0,360)。
这是它的外观(原谅可怜的轴:-)
答案 1 :(得分:3)
我总是使用np.diff()函数来获得更大于180度的点并插入一个蒙版元素。主要的缺点是你还必须为绘图保留一个“索引”。
所以:
a = np.array([10,15,30,90,150,290,350,40,50,20,310,250,150])
idx = np.arange(len(a))
b = np.diff(a)
mask = np.where(np.abs(b) >= 180)[0]+1
c = np.ma.masked_equal(np.insert(a, mask, -1), -1)
idx = np.ma.masked_equal(np.insert(idx, mask, -1), -1)
fig, ax = plt.subplots(figsize=(10,3))
ax.plot(idx, c)
ax.set_xticks(idx)
ax.set_ylim(0,360)
这不会插入范围之外的值,但我想可以添加。您可以插入2个元素,而不是1个蒙版元素,再次插入图形中的“out”和“in”。
另请注意,180度的阈值只是一个假设,除非您实际测量风,否则您实际上并不知道风是支持还是转向。