这是我正在使用的数据的示例:
它是布尔方波的描述,具有以下特征:
需要查看原始点(包括重复的点,如t = 1.2)和线叠加。
我的理解是最简单的方法是在每对之间插入一个点,y值是前一个点的上/下值和下一个点的x值。然后,在散景中,将原始数据绘制为散射,将Data + InterpolatedData绘制为线图。这意味着情节中有两个不同的字形,我宁愿避免(能够使用新的legend.click_policy ="隐藏"),但是可以容忍。
使用常规python代码很容易实现插值,但我更喜欢用pandas找到一种方法来实现代码一致性。大熊猫是这种插值的合适工具吗?
最佳解决方案将导致散景中的单个字形。我愿意牺牲性能来实现这一目标。 一个好的解决方案用pandas代码替换我的纯python代码。
答案 0 :(得分:3)
以下是适用于Bokeh的完整脚本。
{
"channelData": {
"message": {
"chat": {
"all_members_are_administrators": true,
"id": -219911672,
"title": "jlarky-dev",
"type": "group"
},
"date": 1493246056,
"from": {
"first_name": "Test",
"id": 107390199
},
"message_id": 100,
"text": "test"
},
"update_id": 66470785
},
"channelId": "telegram",
"conversation": {
"id": "-219911672",
"isGroup": true,
"name": "jlarky-dev"
},
"entities": [
{
"mentioned": {
"id": "JLarkyTestBot",
"name": "jlarky_test"
},
"text": "JLarkyTestBot",
"type": "mention"
}
],
"from": {
"id": "107390199"
},
"id": "KxBlE8JsLfg",
"recipient": {
"id": "JLarkyTestBot",
"name": "jlarky_test"
},
"serviceUrl": "https://telegram.botframework.com",
"text": "test",
"timestamp": "2017-04-26T22:34:17.4109674Z",
"type": "message"
}
这会产生以下带有交互式图例的散景图:
答案 1 :(得分:0)
这应该让你开始。请注意,matplotlib是直接使用的,而不是pandas(实际上使用matplotlib)来绘制。
import pandas as pd
import matplotlib.pyplot as plt
使用pandas映射数据:
data = pd.read_csv('wave_data.csv', sep=';')
def boolean_map(row):
if pd.notnull(row.Down):
return 0
else:
return 1
data['BooleanMapped'] = data.apply(boolean_map, axis=1)
绘制数据:
x = list(data['Time'])
y = list(data['BooleanMapped'])
plt.ylim(-0.1, 1.5)
plt.xlim(0.9, 2)
plt.step(x, y, where='post')
plt.show()
答案 2 :(得分:0)
正如评论中所述,这是我目前正在使用的代码:
import timeit
start_time = timeit.default_timer()
import io
import os
import sys
import math
import pandas
from bokeh.io import output_file, show
from bokeh.plotting import figure
output_file("signal.html")
def fillSquareWave(xi, downi, upi):
resultx = [0,]
resulty = [0,]
lasty = 0
for x, down, up in zip(xi, downi, upi):
if (math.isnan(down)) and (math.isnan(up)):
# no dropna() at pandas level, since it'd drop if EITHER is a nan (we only drop if BOTH are)
pass
else:
# append extra point
resultx.append(x)
resulty.append(lasty)
# append real, current point
resultx.append(x)
if (not math.isnan(down)) and (math.isnan(up)):
resulty.append(0)
lasty = 0
elif (math.isnan(down)) and (not math.isnan(up)):
resulty.append(1)
lasty = 1
else:
print("x: ", x, " down: ", down, " up: ", up)
assert(False)
return resultx, resulty
sourcefile = os.path.basename(sys.argv[1])
bothpts = pandas.read_csv(sourcefile, usecols=['Time', 'down', 'up'])
uppts = pandas.read_csv(sourcefile, usecols=['Time', 'up'])
uppts.dropna(inplace=True)
uppts['up'] = 1
downpts = pandas.read_csv(sourcefile, usecols=['Time', 'down'])
downpts.dropna(inplace=True)
downpts['down'] = 0
php = figure()
php.scatter(uppts['Time'], uppts['up'], legend='up',)
php.scatter(downpts['Time'], downpts['down'], legend='down')
xdata, ydata = fillSquareWave(bothpts['Time'], bothpts['down'], bothpts['up'])
php.line(xdata, ydata, legend='overlay')
php.legend.click_policy = "hide"
show(php)
print("Rendered in %.2fs" % (timeit.default_timer() - start_time))
此代码生成的图表与问题略有不同 - 它在(0,0)处开始绘制,而不是在CSV文件中第一个点的坐标处。
编辑:可以使用以下代码删除多个read_csv()调用,但执行时间基本不变。
bothpts = pandas.read_csv(sourcefile, usecols=['Time', 'down', 'up'])
uppts = copy(bothpts)
del uppts['down']
uppts.dropna(inplace=True)
uppts['up'] = 1
downpts = copy(bothpts)
del downpts['up']
downpts.dropna(inplace=True)
downpts['down'] = 0