Reputation: 799
I'm following a Udemy tutorial on Bokeh and I've come across an error that I can't figure out how to solve, and haven't received a response from the tutor. Initially, I thought there was something wrong with my code, so spent about a week trying to figure it out and finally give in and copied the tutors code only to find the error persists.
The purpose of the code is to scrape and plot live data. Code below:
from bokeh.io import curdoc
from bokeh.models import ColumnDataSource, DatetimeTickFormatter
from bokeh.plotting import figure
from random import randrange
import requests
from bs4 import BeautifulSoup
# Create the figure
f = figure()
# Create webscraping function
def extract_value():
r = requests.get("https://bitcoincharts.com/markets/okcoinUSD.html", headers = {'User-Agent' : 'Chrome'})
c = r.content
soup = BeautifulSoup(c, "html.parser")
value_raw = soup.find_all("p")
value_net = float(value_raw[0].span.text)
return value_net
# Create ColumnDataSource
source = ColumnDataSource(dict(x = [], y = []))
# Create glyphs
f.circle(x = 'x', y = 'y', color = 'olive', line_color = 'brown', source = source)
f.line(x = 'x', y = 'y', source = source)
# Create periodic funtion
def update():
new_data = dict(x = [source.data['x'][-1]+1], y = [extract_value])
source.stream(new_data, rollover = 200)
print(source.data) # Displayed in the commmand line!
# Add a figure to curdoc and configure callback
curdoc().add_root(f)
curdoc().add_periodic_callback(update, 2000)
Which is throwing:
Error thrown from periodic callback: IndexError('list index out of range',)
Any ideas on what's going on here?
Upvotes: 1
Views: 794
Reputation: 2277
Change your update function like so:
# Create periodic funtion
def update():
if len(source.data['x']) == 0:
x = 0
else:
x = source.data['x'][-1]+1
new_data = dict(x = [x] , y = [extract_value()])
print("new_data", new_data)
source.stream(new_data, rollover = 200)
print(source.data) # Displayed in the commmand line!
There are two issues with your code:
y
. Thus, y
will not contain the returned value.source.data['x']
is an empty list on the first call of update(). Hence, you try to access the last element (via [-1]) of an empty list. This give you the error IndexError('list index out of range')The solution for 1 is trivial. For 2, it is similar to what you tried to do before. But first you check if source.data['x'] is empty. This will be the case on the first call of update. There, you set x to 0. On following executions, when the list is non-empty, you take the last value in the list and increment it by one.
Upvotes: 1