 going to be talking at 3.15 about really diving into the interactive component and building sort of bokeh apps, bokeh dashboards and stuff. So it'll be a really great segue this afternoon. So data at the heart of bokeh is the model, the column data source. And it's very simple. It's just a table of data just like you might expect. And so that's not a good sign. So we take a data dictionary in Python, a normal dictionary, keys, array. And we also, how many people here have worked with pandas? OK, almost everybody. If you haven't worked with pandas, it's fine. It's a lot like Excel, but way better in Python. And it's not a lot like Excel. It'll change your life. But the core of it is you can pass it a dictionary and you get out a table of data. And there's lots of other ways you can read from Excel, from JSON, from CSV, and so on. If you haven't used pandas before, I would totally recommend Brandon Rhodes' pandas tutorial from PyCon 2015. It really boils down like how to really just understand it, but keeps it at a nice, simple level. And so you can make your column data source from either a dictionary or from a pandas data frame. And your data ends up represented like that. And you'll notice the one difference between when I pass in my dictionary and when I pass in my data frame is that I've got this extra key value here. The index has come from the pandas data frame. It's this left index here that it's named index for us. So that is the column data source. The next thing that's at the heart of Bokeh is the plot. And I'm skirting over some details here, because I don't think they're that important. There are these models, plotting, charts, these three different ways to use Bokeh. But they have a lot in common. And you should find it pretty easy to jump between the three levels. But I think it can be a bit confusing knowing exactly what to do from the get-go, which is why I'm trying to show you all three. So at the lowest level, we have the plot object. The next level up, we have the figure. And finally, we have the charts. They're all different things. They come from different modules within Bokeh. But you're going to see they all have the same attributes attached to them, like a toolbar location, background fill, and so on. So once you're working with one, you can reasonably assume that the other one's going to behave similar. And they all have three really important methods on them. Add tools, add layout, and add glyph. And if you can remember those three methods, you're going to get a really long way into building all of your plots. Glyphs, I hear you say. No one said glyphs. OK, glyphs, to me, the word means nothing. I was so confused for a long time. It just means shapes. And I don't know why it's called glyphs. I'm sure there's some very, very logical reason. But glyphs are just shapes. And so this is actually from the examples. And these are all of the different kinds of shapes that you can spell within Bokeh. And in some combination of all of these, there's a whole other set here. In some kind of combination of all of these things, you can make pretty much anything that you could think of. If you couldn't, I'm sure we would add another one, but we really have got most things covered here. So glyphs are just shapes. So we're building a dashboard. We've talked about data. Let's talk about charts. But I keep going on about this models plotting charts thing. And I want to just lay it out a little bit more. So there's these three modules, Bokeh.models, Bokeh.plotting, and Bokeh.charts. Bokeh.models is the lowest level of Bokeh, but it doesn't mean it's a level you should be afraid of. It's an awesome level. I love to live in the models level. Everything above it is built on top of models. So it offers you the most control, but it doesn't mean you have to do all the work yourselves. On the complete opposite end, you have Bokeh.charts. These are one line functions that let you spit out a bar chart, spit out a line chart, spit out a horizon chart. It just takes your data frame and gives you something awesome. So it's very, very quick to use, but it sort of does all the magic for you. Bokeh.plotting kind of lives in the middle and you have to sort of organize your data for it, but it then tries to pick sensible defaults, so you don't have to add the axes and add the grid and so on. So it tries to sort of give you something you want, but it gives you a bit more control. Where you want to work is really a matter of personal taste. Personally, coming from a web world, I started with charts, and charts for me were a gateway to models, but I think a lot of people coming from the data science, the data science world find plotting sort of more intuitive. But you'll see them all, and you can choose what you want. So let's start with charts. So this is one little pocket of the dashboard that I was demoing, and this bar chart here has come out of the charts interface. So one of the things about the charts interface is that it kind of does some magic. It just takes your data and spits out a chart. So you kind of need to know what it wants the data to look like, otherwise it can't do its magic. So often when I'm getting started with the chart, especially if I haven't used it before, I'll just set up some dummy data to make sure it's kind of roughly doing what I expected to do before I put in my real data, because then who knows whether it's okay or my data that's being weird. So we just have a simple thing here. We've spent some time with ponies and unicorns and other magic things. And now we get to importing our bar chart. And so we've imported it from the charts function. We import bar and now we just call it with our data frame and we show the bar chart one line. And here we have our chart. We have zoom, we have reset, we can save it, we can do that, we can resize it. And this is a web object. You could share this HTML. It's all gonna work beautifully for you. So that's working how we expected to. So now we're gonna try with some of our real data. All of the code that gets all the real data is in that repo that I shared with you earlier. I'm not gonna cover how I made it today. This is the raw data. And then this is the sort of process data that I did. So once again, I spit out my data. That's, I spit out my bar chart, which is almost how I want it. So now I'm gonna add a couple more options. I'm gonna stack my bar chart and I'm gonna set a palette. And now it's starting to look a lot like what I showed you earlier. Styling is later in the talk, so we'll get to that in a bit. So there we go. One line, bar chart, it's interactive. You can add hover, you have zoom, and there you are. What I didn't, what I forgot to put in was a list of all of the different kinds of charts that you can import. But at the moment, it's all the ones you might expect, line and time series and horizon and scatter and so on. So next up is IO. What you might have seen me do at a couple of the top of those notebooks is from bokeh.io import output notebook and show. And when I call output notebook in an IPython notebook, I see this bokeh.js successfully loaded. So that's how we work with bokeh in a notebook. And then there's also this output file, which is the sort of equivalent. And so then at the top of my notebook, I would call output file and I would give it an HTML file name. And then when I hit show, instead of showing in the notebook, it opens a new browser with my static HTML has been saved and I could share that with somebody. I like to use this extra argument mode equal CDN, which instead of dumping all of the JavaScript and CSS that power bokeh inline into the HTML, it just puts in a reference to the bokeh CDN, which takes your HTML from sort of 1.6 megabytes down to about 6K for a small plot. So it's a decent bandwidth saver. So yeah, so that's how you get started with spitting your stuff out. So plotting, we've done the charts interface and now we wanna look at the plotting interface. This is a plot that I couldn't build with the charts interface. There isn't a chart that's sort of pre-baked for me that does this. I have this categorical axis on the left side here, splitting up the different kinds of activities that I get up to. I have a time series axis on the bottom here and then I have these rectangles that I've plotted across. So once again, I'm gonna try with some test data first. This time, I'm gonna build my own column data source. You notice I didn't have to do that with charts. I just threw in a data frame and it just spat out a chart. But this time, I'm gonna have to build my own column data source and I'm gonna do it by passing in a dictionary. And then I'm going to instantiate my figure. Now, figure doesn't do anything on its own. In fact, if I just do show P here, what I get is a very helpful error message. It's just come into Bokeh saying, you have no glyph renderers. I'm not gonna be able to plot anything interesting. So we're starting to this sort of validation and error helping is new. And so it's a bit spotty. So there are some bits that do it and some bits that don't. So if you ever see a place where you're like, oh, why didn't it give me an error message? Just throw up an issue on GitHub because we keep adding these in. So once we have our sort of empty figure, now we have a whole bunch of methods on it. Remember all of those different glyphs that I showed you over and over and over again? For every one of those glyphs, there's a method. So there's P dot quad to plot a quad. There's P dot rect to plot a rect. There's P dot circle to plot a circle and so on and so forth. And so for our one, we're gonna use the quad, what do you call it, method and spit out a plot. This was just dummy data. So I just have linear axes on the left and bottom here. And so now let's think about how we might do this for our plot. So here's our data. We have the start and the end in time of each of our blocks of time and then we have our categorical name for our label for each of those time blocks. So we're gonna try plotting this. And it's not looking great. It hasn't given us anything. And if I open the console, what I'm gonna see is, although I tried to pass it some data and I really did try, if I open the console, it's gonna say could not set initial ranges. And if you're thinking opening the console really, this is where these requests for more validation can come in. Like this is totally something that we could have put one of those error messages in for we haven't done it yet. So we should do that and I'm sure it will come. But going to the console is always a good place to look if things didn't work how you expected to. So what happened was, instead of if I had linear data, like I had had up here just a series of numbers, when I instantiated my figure, it was clever enough to figure out that, okay, I can figure out the ranges, this is no big deal. But when I passed it, my data with time and categorical axes, it's like, I don't know what you want me to do here. Like you've got to give me some help. So now when we're instantiating our figure, we are going to specify the range, the time series, and we're gonna specify the categories on the left side. When we do this, we get out something that looks pretty good. But not quite right. What you can see is our little blocks of time are like teeny tiny. I don't know if you can even see that in the back, but they're there, but they're just really small. And so what happened is, how do you specify height on a categorical axis? This is a bit of a tangent, but it's a good one to know. So when you have time or naught to 10 or whatever, it's pretty obvious how you specify height or width. When you have a categorical axis, what does that mean? And so the way we do it in bokeh is from the left to the right of your categorical axis, or the bottom to the top, is naught to one. And so you append a colon to your label and you add like 0.1 for the bottom to 0.9 for the top or the left or the right or whatever. And so once we've done that, if we try again, now it's come the height we expected to. And so if I change this to be 0.4 to 0.6, they'd be much narrower and so on. So you can play with that as you wish. And one of the things you're seeing here is think about that original data frame. That original data frame, the chart that I showed you was essentially a switched around version of this. The chart function did all of that magic for you. It magically figured out how wide I'm gonna make things. It processed all the data, set that all up for you so that you didn't have to think about it, which is awesome until it doesn't quite do what you need it to do and then you have to do it yourself. And actually, to be honest, one of the ways I learned Bokeh was I started using the charts and then I went and read the code for the charts to figure out how it was doing it all and then I was able to build my own. So there we go. Okay, so that was plotting, a little bit more verbose, but a lot more control. You can do lots of different things there. And so last but not least, we get onto models. And so this is where we use the lowest level of Bokeh to build up our charts. In the docs, I'm pretty sure I read somewhere that it's like most people wouldn't need to do this, but I like living down here, but each to their own. So once again, I've pre-processed all my data and I've made a dictionary of data sources that I want to plot, which looks something like this, which is nice. So this should look somewhat familiar. This is our first attempt at making a plot and this should look a lot like what we just saw in plotting. We are specifying the X range and the Y range because if we don't Bokeh or FreeCal, now instead of we're not calling a method just yet, we're actually specifying our line here. So when we specify our line, we've imported line from Bokeh.models and we're saying I want the X to be powered, if you like, by this column called timestamp. I want the Y to be powered by the column called cumesum hours. And then what I'm gonna do is I'm gonna loop through and I'm gonna add lines for each of my data sources that I want to add. So it's allowing me to add lots of different lines. And so to do that, I use that addGliff method that I talked about before and I pass in a column data source and I pass in the specification for my line. So when I do that, this is what I get, which is what I asked for, but it's not beautiful. And that's because down at the models level, we really do have to spell everything out. So the first thing we might wanna spell out is some color and Bokeh has a whole bunch of built-in palettes for you that I would totally recommend using as defaults but you can of course spell your own palettes and palettes are just a list of either hex or IGBA two-pulls or a whole different bunch of things and you can see the reference at the palettes documentation. So let's try again with a little bit more style. Again, we just have our ranges specified. Now we're gonna try a bit of background fill, a bit of border fill and sort of mess around with this and now we're gonna add some layout. So this is where we're adding our linear axis on the left and our date time axis on the bottom. And then now our line, the specification has got a little bit more complicated. We're not only specifying the X and the Y, we're specifying a color, we're specifying some line width and so on and then once again, we're just adding, using this addGliff method, use the source. It's how they use the force, use the source and use the source and add the line. And once we do that, things start to look pretty promising. And so we can really start messing with this. So if I just turn this into a method so I can make it nice and repeatable. And now what I've done is I wanted to add, so this has no tools on it, right? The charts and the plotting came with all those tools just poof out the box. Now we have to manually add the tools ourselves to do this, it's very easy. You just use addTools and you specify the tool you want to add and now we have pan added and that's awesome except I don't really want it to pan up and down because that doesn't make any sense for my data. So I'm gonna try constraining it. So constrain equals width. Oh, that didn't work, that's weird. What happened? Oh, thank you, Bo K. It has told me that constrain is an unexpected attribute and the things that it's expecting are dimensions named plot-sessional tags and so this part of the error reporting of Bo K I find incredibly useful. If you, if I can't remember what it wants, I'll often just put in garbage so that it tells me what it's expecting which is really handy. So it said it wanted dimensions. So, oh, I Python fail. Oh, I think I just deleted my cell, hang on. No, where did it go? Oh, it's there, thank you. No, I changed it to markdown. There we go. So it said it wanted dimensions. I think it said that. It did say that but now it's saying it got an unexpected error and it's looking for a list and the list has to either contain width, height, X or Y but it just got width, it didn't get a list. So again, there's the properties reporting and then there's this value reporting which is part of what we use to help us be able to serialize from Python to JavaScript but it's also a very helpful for debugging your code as you go. And now, has our, it pans left and right and I can't go up and down however much I might wanna try. So we can keep going and going with that but I will spare you for now. So, quick mention of the examples in the Bokeh repo. So there's the gallery on the website but if you actually download the repo and find the examples directory there are just a bajillion examples in there and in particular for getting started with models they're incredibly helpful so I would totally recommend just downloading them and running them. So, styling. We started to see a little bit of that just now on the models but styling is possible for every single level for plotting charts, models, it just depends on how you want to do it really so I'm gonna show you for charts and models and take a pic. So, in the interest of time I'm gonna skip the little prototyping but on, this is us making a bar chart just like we did earlier and once we've got that we can then just start to set all of the attributes the toolbar location, the background fill, the outline and so on. We go and we grab the glyphs and we can specify their fill color, the line color and we set the attributes and we set the attributes and we set the attributes and then finally we show it and it looks gorgeous and so when you're in the IPython notebook the one of the nice things about it is the auto complete and the fact that you can really use IPython notebook to help you see what the attributes that you might have available to you are and so that's one of the ways that especially early on I used to play around with Bokeh a lot. Now with models, we spell it all first, right? We don't create something and then fix it we spell it all as we go and so what I like to do is and the other thing we like to do if we're making lots of plots and we all want them to look the same is we can start to build these dictionaries of properties like our line colors and so on and we can just splat them into all the axes or we can splat properties into all of the plots so I typically build up this style sheet and the top of the style sheet I'll have my colors and padding and things like that that will sort of mirror my CSS if I'm building a website and so that I can sort of have those common colors and things like that across and then I have this plot properties dictionary, access properties dictionary and so on set up in just a file called constants and then when I come to build my plot in models it actually starts to look quite clean I just make a plot and I put in the plot properties I make my two axes they show all these common stylings again I make my two rectangles they show all these common stylings and so this is why I kind of like working with models is because I'm doing a lot of heavy customization typically and I find this fairly clean as opposed to that big sort of quite verbose version that you end up doing where you fix all the attributes on a chart but each to their own anything is possible So, layouts there's... if you're just working within Bokeh you're not interested in putting stuff on the web there's plenty that's sort of in the box to help you make something nice from the get go in particular there's Hplot and Vplot that are in Bokeh.io and what they do is they just kind of make rows and columns and it's pretty self-explanatory so we've got here a Vplot and we've nested inside it an Hplot and two charts so our Hplot across here we've sort of lined up our three things this is not my dashboard this is just sort of giving you a demo of what you know what you could do and then I've stacked it on top of some other plots and so you could spit that into an HTML using the output file method and you're going to get something that's pretty presentable and all of these plots can interact with each other once they're in the same document together if you spell it all in a nested thing like this all of those things will be able to interact together because I typically sit in the web I use... if that's the very high level I use the very low level embed function and again to use this I use the components method and I take a dictionary of all of my plots and what the components method gives me back is my HTML script and a dictionary of all of the divs that I have to... the div tags that I have to stick into my HTML so I'll take a template this is a very simple one where I've just imported bokeh and maybe some CSS at the top and then I've started to template in the divs that bokeh has given me back and I template in very important my script and using that, rendering that out with the context of the script and the divs which if you're in... this works in Django, JINJA whatever your templating language is it's all the same bokeh comes with JINJA built in so that's kind of convenient you can start to build... this is an HTML page right ahead H1 building a dashboard my time selector and this is the actual HTML page that I could either be rendering through a web application or as a static HTML so that's layout and I'm pretty sure Fabio is going to talk a bit more about embedding and stuff in more detail later so if that was too fast they'll be more and so with all of that under your belt I promise that adding to it the pandas data frame method to HTML which turns your data frame into a nice HTML table you can make everything that you see here these tables here are pandas tables this is our plotting plot these are our bar charts these are our line charts and we've got it all with a nice, you know and what's different about it is I've used a I've used a nice template I've used some nice CSS and it all comes out very nicely so last but not least interactive so there's two parts of interactive the first part has been built into bokeh for quite a while we have our tools like hover select zoom pan which we've been talking about a little bit and the shared selection and panning so I'm going to quickly run through how to do that so just getting started I have a simple set of data and the first thing I'm going to do is I'm going to share some ranges and so what I've done here is I've got a figure I've got three figures, sorry that I've sat side by side and in the second figure I've used P1's X range and in the third figure I've used the P1's X range and its Y range and so when I do that it means that if I pan left to right it's going to pan out on all of the plots when I pan up and down because I only shared the Y range with one other plot only one is changing so this lets you sort of there's lots of different times when you might be wanting to see different dimensions and how they compare so you can plot different dimensions on different plots but start to move around in sync which is very handy the other thing that we've done here is we've shared a source across them so instead of making different sources for different plots I use one source with all of my data in it and I shared it across my three my three different plots but I plotted different things so my left plot has X and Y naught my middle plot and so on and so once I've shared a source when I start using selections they can when I start using selections they'll share across they'll share across all the different selections this is I'm running a bit low on time I'm very sorry about that this is the spelling for how to do hovers which I'm not going to talk about I'm going to whip through interactions to show you so this is but this is a quick example of something very nice I did with linking selections so when I click on a country this number here update the name of the country updates the value updates when I click over on this other tab I've also shared it across tabs and so Mali has updated here when I click on Ghana if I go back to my first tab Ghana will still be selected so that's a bit more sophisticated example of what you can do with that linking and last but not least I have four minutes and 14 seconds to whip you through callbacks and then Fabio is going to really take this and run with it this afternoon so callbacks have just been added to Bokeh and they're super awesome they allow you to write a tiny piece of JavaScript or a giant piece of JavaScript if you want to but you write some JavaScript in your Python code and you can start to do really sophisticated interactions and they're currently available on the sort of weird and somewhat ad hoc subset of all of the components of Bokeh and that's the list there and as a web developer I really love this because what I really want is that that really rich kind of experience nothing crazy fancy not doing sort of computation on the server or whatever but giving people the chance to really play with their infographic a little bit and this has really allowed me to do this so this is one I built recently they've got this slider at the bottom this is a Bokeh slider and what I'm doing it's very simple whenever I slide the value of this number at the back here changes and the data source that powers the circle sort of switches out so this is something that is a completely standalone piece of HTML all done in Bokeh using this new callback mechanism if you hate JavaScript more than life itself there are we're starting to in the same way that we made charts as these sort of canned one-liners that will sort of do all the magic for you we're starting to build up these actions so a common thing might be you tap on it you select a glyph and a URL opens so the first action we've made is open URL but there'll be more sort of pre-built things so you never have to write JavaScript coming here is an example of how to use of how to use the callback so excuse that typo where it just says code equals blank there so let's say so that we call we make a callback and we have some code like change the selected value to a new thing and when now instead of just adding a tool hover tool we add it with our callback what's exciting here and is a little hard to see but when you get used to it you realize how magic it is is I have passed I've passed in these arguments and what I've done is I've given a name my column data source and I've passed in the Python object so now when I in my JavaScript code I can use the word I can use my column data source as a as a JavaScript object and I can start playing with it and it's like I was playing with my Python object so you don't have to do any magic you can sort of be playing with your Python objects in in JavaScript and if you use that components method where you just have them all in one components method and all in one script that's how you can start interacting across all of your different plots and Fabio is going to to show you all about that later so with one minute left are there any questions? yeah you can shout I can repeat it yes you mean like a Google map or an open street map or whatever there oh sorry the question was it can you can you embed a Google street map a Google map or an open street map or something like that there is a there is actually a G map plot like bar chart or something like that like a plot that you can instantiate which works okay and but we wanted to make it better and one of the things that I meant to be doing this summer is actually working on our mapping support in general which is not as hot as we would like it but it's really high on my to-do list because it's something I want to see done so yeah Sara told us in the afternoon we have the possibility to learn a little bit more about bokeh so I want to thank you for your talk we have now