Skip to main content
Data Visualization and Interpretation

Bokeh: Interactive Visualization in Python

Published: 2026-08-11
Level: postgraduate
Audience: Postgraduate students in data visualization and business intelligence

Prerequisite Knowledge

This lecture builds on the following concepts from earlier lectures. If any feel unfamiliar, review the linked notes before proceeding.

Previously Covered in This Subject

  • Interactive visualizations — covered in Lecture 4 (Interactive Visualizations)
  • The four dashboard types — covered in Lecture 9 (The Four Types of Dashboards)
  • Building dashboards from sheets in Tableau — covered in Lecture 10 (Tableau Dashboards: Sheets First, Assembly Second)
  • Python as a visualization environment — covered in Lecture 12 (The Shift from Tools to Python)
  • Installing a Python library and checking its version — covered in Lecture 12 (Installing and Checking the Version)
  • The pyplot interface and the import line — covered in Lecture 12 (Pyplot — the Plotting Interface)
  • Markers in Matplotlib — covered in Lecture 12 (Markers)
  • Line styling and multiple lines — covered in Lecture 12 (Controlling Lines)
  • The layered architecture of a plotting library — covered in Lecture 12 (The Layered Architecture of Matplotlib)
  • Scatter plots with plt.scatter — covered in Lecture 13 (Scatter Plots)
  • Vertical and horizontal bar charts — covered in Lecture 13 (Bar Charts)
  • Histograms from random data — covered in Lecture 13 (Histograms)
  • The official documentation and gallery — covered in Lecture 13 (Matplotlib's Documentation and Community)

This session introduces Bokeh, a Python library for interactive, web-browser-based visualization. The lecture builds up from zero: what Bokeh is, why it exists alongside Matplotlib and Seaborn, how the library is organized, and — through a long series of live demos — the glyph functions that create lines, scatter markers, bars, and histograms. By the end of the session you will have seen every major plot family in Bokeh, a clear sense of when to pick Bokeh over the other plotting libraries, and the core workflow (figure, output file, show) that every Bokeh program follows.

15.1 What Is Bokeh

15.1.1 Definition and Core Idea

Hook: What if the chart on your screen were a living object you could drag, zoom, and click — instead of a fixed picture? That question is the entire reason Bokeh exists.

Bokeh is a Python library that generates interactive visualizations in the web browser. You will hear that one phrase over and over because it is the whole point of the library: the plots are not pictures on a page, they are living objects you can touch. You can drag the chart around, zoom into a region, and save the result — all inside the browser, with zero extra work. When you hover over a point you can read its values, and when you click on parts of the plot you can filter or interact with the data underneath.

Definition — Bokeh: a Python library for building interactive, web-browser-based visualizations. An interactive visualization (a chart you can touch) is one where the reader can change the view — pan, zoom, hover, select, filter — rather than just look at a static image. Written as code, run from Python, output delivered as an HTML page in the browser.

Formally, Bokeh is built to create complex and interactive plots that can be integrated very easily with web applications. That last part is the differentiator. A plot you build in Bokeh can be embedded in a web page and become part of a larger application, not just an image that sits inside a report. The word that appears in every bullet point about Bokeh is interactive: interactive plots, interactive visualizations, interactive dashboards, tooltips, clicking, filtering. So if the question is "I need a lot of interactive visualization," Bokeh is the library for that job.

Intuition. Compare the two ways a chart can reach your screen. A static chart (like a Matplotlib or Seaborn figure saved as PNG) is a photo: it shows one view of the data, decided in advance by the person who drew it. A Bokeh chart is more like a map app on your phone: the same data is there, but you are the one who decides how close to zoom, which region to pan across, and which point to poke for details. The reader becomes an explorer, not a spectator. Where the analogy breaks: a map app needs a connection to a live data service, while a Bokeh chart is a self-contained HTML page — the data is already inside the file.

A dashboard (a single screen that brings several charts and controls together so you can monitor a situation at a glance) is exactly where this model shines: several interactive charts side by side, each one zoomable and clickable, all in the browser. This course's earlier classes built dashboards with Tableau by dragging and dropping; Bokeh reaches the same end point in code.

15.1.2 The Interactive Toolbar

Every Bokeh chart comes with a default toolbar that delivers the interactivity for free. These features arrive with the chart whether you ask for them or not, and they are the same set you get in every Bokeh plot:

  • Pan (move): you can grab the plot and drag it in any direction, exactly like moving a map.
  • Reset: a refresh icon brings the plot back to its original shape after you have panned or zoomed.
  • Box zoom: you click the zoom tool, drag a rectangle over the region you care about, and the plot zooms into that selected area. You can then zoom again into a smaller region, so a very busy graph with many points can be inspected level by level.
  • Wheel zoom: rolling the mouse wheel zooms in and out continuously, based on how fast and how far you scroll.
  • Save: a save button exports the current view of the chart as a PNG file.

Visual intuition. Picture the toolbar as a thin strip of icons running down the right edge of the chart (in newer Bokeh versions it can also sit on top). The chart itself fills the rest of the window. Pick a point in the middle of the plot; with wheel zoom the whole chart stretches smoothly around your cursor, the axis tick labels at the bottom and left renumbering as you go. Drag with pan and the same data shifts under your cursor like a sheet of paper on a table. Hit the reset icon and every axis snaps back to its starting range — the original shape returns because Bokeh remembers the view it started with. The takeaway: five icons, zero code, and the plot becomes an instrument rather than a printout.

The running comment during the demo was: imagine doing all of this on a web page inside your dashboards — how useful would that be? All of this interactivity was present in the very first five-line example, with no interactivity code written at all. Because a Bokeh plot is interactive, it also has to remember every picture and every layer it renders, which is exactly why the layering and glyph machinery (Section 15.9) exists.

15.1.3 Student Questions and Answers

Q: Has anyone had any exposure to Bokeh before, even the simplest exposure? A: One student confirmed it was a completely fresh start. The rest of the class stayed silent, and the silence was treated as "no." So the class began from the very basics — nobody was expected to know anything about Bokeh.

That opening exchange set the pace: everything, from the definition to the first line of code, was explained as if no one had seen the library before. The consequence for you as a reader: no prior Bokeh (or even Python) experience is assumed anywhere in this session, and each concept is built up from zero.

15.1.4 Common Pitfalls

  • Expecting one fixed image. Students who come from Matplotlib sometimes try to "view" a Bokeh plot as a static file and miss the point. The output is an interactive HTML page; if you only look at it as a picture, you are seeing a fraction of what Bokeh does. Open it in a browser and touch it.
  • Confusing "interactive" with "animated." Interactive means you control the view (pan, zoom, hover, click). An animated chart changes by itself. Bokeh gives you the first; the second is a separate idea.
  • Expecting interactivity in Jupyter or Colab to behave like a website. Bokeh renders fine inside notebooks, but the full toolbar experience lives in a browser tab; if you are in a notebook and the plot looks inert, check that the output is actually the interactive HTML widget and not a pasted screenshot.
  • Assuming Bokeh is only for dashboards. Interactive web visualization is its focus, but the same machinery draws a plain line graph or scatter plot — you saw simple examples in the very first demo, which was five lines long.

15.1.5 Where This Matters

Interactive dashboards are the everyday home of Bokeh. In industry, a dashboard is a screen that monitors many types of data at once — a trading desk watching market feeds, a logistics control room tracking shipments, an IT operations team watching server health. The dashboard design literature divides them into roles: strategic (a quick high-level health check for executives), analytical (digging into why something changed, with filtering and drill-down), and operational (live monitoring of current activity, updated continuously). Bokeh's free pan/zoom/hover/tooltip behavior is the natural fit for the analytical and operational roles, where the viewer must interrogate the data — hover for exact numbers, box-zoom into a suspicious spike, filter what is shown — rather than read a pre-rendered answer.

Recap: Bokeh = Python library for interactive, web-browser visualizations, with a default toolbar (pan, reset, box zoom, wheel zoom, save) attached to every chart for free. Next, the lecture asks the natural follow-up question: why choose Bokeh over the libraries you already know — which is where the comparison to Matplotlib and Seaborn begins (Section 15.2).

15.2 Why Use Bokeh

The lecture's definition answered what Bokeh is. The next block answered why you would reach for it — five reasons, each building on the one before. Keeping them separate matters because they are different kinds of arguments: two are about the output quality, two are about fit with web work, and one is about the ecosystem around the library.

15.2.1 Interactive and Engaging Visualization

The first reason is the one you keep hearing: interactive and engaging visualization. With a Bokeh plot you can zoom, you can filter data with the plots, and you can see tooltips when you hover. A few of these properties were shown in this class, and the rest are covered in the next session. The interactivity is what turns a chart into an exploratory tool rather than a static figure.

Intuition. A static chart answers the question the author expected; an interactive chart answers the questions the reader thinks of while looking at it. A tooltip (the small box that appears when you hover over a point and shows its exact values) is the simplest example: without it, reading a precise value off a busy scatter plot means squinting at axis ticks. With it, the number comes to your cursor. The same logic scales to filtering: a reader who can click a legend to hide one series is comparing alternatives that the author never anticipated.

15.2.2 Cleaner and Sharper Plots

Bokeh output is much cleaner and much sharper when it comes to the final visualization. This is not an absolute criticism of the other libraries — the point is that every package is getting cleaner and sharper over time, and Bokeh is among the leaders. That cleanliness and sharpness is one of the reasons so many people who need interactive plots choose Bokeh.

Visual intuition. Imagine the same scatter plot rendered two ways. In the first, the points sit on a white background with thin gray gridlines and small, tidy tick labels; in the second, the same data looks slightly heavier — thicker axes, busier gridlines, larger default margins. Bokeh's default styling sits toward the first end of that spectrum, and its anti-aliased HTML rendering keeps lines and circles crisp at any zoom level because the browser redraws them, rather than stretching a fixed image. Clean defaults matter because the chart's job is to put the data in the foreground, not the furniture around it.

15.2.3 Web Integration

All three plotting libraries (Matplotlib, Seaborn, Bokeh) integrate with Python, so that line applies to all of them. What Bokeh has an edge on is web integration: you can embed your visualization in a page, pass the page around, and integrate the chart with your web pages. The charts are genuinely deployable as HTML and JavaScript, which is what makes this possible.

Where the other libraries hand you an image file that you then paste into a page, Bokeh hands you a page element — the chart is a self-contained piece of HTML that carries its interactivity with it. That is why Bokeh, unlike the static libraries, shows up inside real web applications rather than inside reports.

15.2.4 One Library for Both Simple and Complex Charts

Bokeh is not only for fancy interactive dashboards. It can cater to both sides of the spectrum: you can still create the basic graphs — scatter plots, line graphs — and you can also handle complex visualization needs like heat maps, very customized layers of components, and heavily customized visualizations. So one library covers the simple user side and the complex side, and what it adds on top is interactivity.

Scope note. "One library for both" is a promise with a shape: the simple side is the entry point (five lines of code get you a working line chart), while the complex side is what the library is capable of (stacked layouts, linked plots, server-driven updates). You do not have to buy the whole capability up front — you start at the simple end and climb as your needs grow. That is a deliberate design choice: the same figure object that made the five-line chart later holds dozens of layered glyphs, so there is no second library to learn when your dashboard gets serious.

15.2.5 Open Source with an Active Community

This reason applies to all three libraries, not just Bokeh. Matplotlib, Seaborn, and Bokeh are all open source, free to use, with very large and active communities. Any support you need — help, code, an issue you file — gets a good response because these libraries have been in the market for quite some time and there is a lot of support behind each one.

What "active community" buys you in practice. When a library is free and widely used, three things follow. First, documentation pressure: the project cannot hide a confusing feature, because too many people trip on it publicly. Second, answer supply: any error message you meet has probably been asked about before, and the working answer is a search away. Third, longevity: a library backed by a large community keeps being maintained — new Python versions supported, old bugs fixed — which matters when you build something that should still run in three years.

The takeaway from the five reasons: Bokeh is chosen when the chart's audience is a person at a screen, not a page in a printout — and next, the lecture points at the official website, because that is where you see the interactivity before you write any code (Section 15.3).

15.3 The Bokeh Website and Documentation

15.3.1 Tour of the Home Page

The Bokeh home page is a genuine teaching resource on its own. The site shows how to get started with Bokeh, what your first steps are, and how to install it. There is a section listing basic charts, a full user guide, and a gallery of charts. The gallery matters: it contains a large number of charts the library can create, and every single one of them is interactive. You can point your mouse at a chart and see exactly what data it holds, which shows the tooltip behavior that comes with every Bokeh chart. Every chart in the gallery has the sample code behind it on the website itself, so you never have to guess how a given chart was built.

What to look at on the site, in order. Start with the installation note (the two commands from Section 15.5), then the basic-charts list — those are the glyph calls from Sections 15.10 through 15.15 in one glance. Spend your real time in the user guide when you want to understand why something works, and in the gallery when you want to see what is possible. The gallery page is where the "interactive" promise becomes visible: every example is live on the page, so the tooltip and pan/zoom behavior is shown, not merely described.

The variety of templates is the point: whereas tools like Tableau offer a specific, limited set of charts, Bokeh has effectively no limit — the gallery keeps going. Anyone interested should explore the gallery, or at least familiarize themselves with what kinds of charts are possible, because a one- or two-hour class can never walk through all of it. The documentation is mature and very good; if you have the appetite and the interest, you can go through it yourself and play around in your free time. The sample code on the site is also how several of the examples in this session were prepared — it is always good to rely on what the original source says.

How professionals use a gallery. The workflow is: (1) you know roughly what chart you want — say, a bar chart with counts per category; (2) you open the gallery, find the closest example, and click it; (3) you copy the sample code and replace the example data with your own. You are not "cheating" by doing this — adapting the official sample is faster and safer than reconstructing every parameter from memory, and the sample code is maintained by the same people who maintain the library, so it uses current syntax. This is standard practice in industry: before writing a chart from scratch, engineers browse the official gallery of a visualization library, pick the closest example, and adapt the sample code. The Bokeh website supports exactly that workflow.

Pitfall — a gallery is a menu, not a manual. It is tempting to scroll the gallery and think "I still don't know how to build this." The gallery answers what exists; the user guide answers how it is built (and every gallery chart links to its own sample code, which bridges the two). If a chart looks interesting, open its code before closing the tab — that small habit is what converts browsing into learning.

Recap: The website is the library's front door: installation notes, basic charts, a user guide, and an interactive gallery where every chart exposes its sample code. The lecture's own demos were prepared from that sample code — which is exactly the pattern to copy when you build your own charts.

15.4 Prerequisites

Before the first code demo, the lecture cleared the ground: what software must be on your machine, and what knowledge you need in your head. Both answers are deliberately short — the whole point of the section is that you do not need much.

15.4.1 Software Prerequisites

Bokeh is built on top of Python, so a working Python installation is a must-have. To install any package you also need a package manager — typically pip. You have already used the pattern: you say pip install followed by the package name, the package manager downloads all the files, installs them, and confirms "yes, I have installed bokeh." If you are working in notebooks like Jupyter or Google Colab, those environments come with predefined installations for these basic libraries, so you often do not have to install anything at all. The pip-based install only becomes necessary when you are working from a plain prompt-based environment.

Why pip exists. A Python package is a folder of code that other code imports. pip (the standard package manager) does three jobs with one command: it finds the package on the public package index, it downloads the correct version for your Python installation, and it places the files where import can find them. When the terminal prints a confirmation line after pip install bokeh, that message is pip telling you the third step succeeded. If you ever see "ModuleNotFoundError: No module named 'bokeh'", the usual cause is that step 3 never happened — the package is simply not on this Python installation, and the fix is the install command itself.

15.4.2 Knowledge Prerequisites

From the knowledge point of view, you need basic Python knowledge — not a high-flying data scientist, just the basics. Specifically:

  • Basic Python syntax and the ability to debug when something errors: understand what is missing, whether something is case-sensitive, and where the error message points.
  • An idea of how to play with data structures: arrays, lists, dictionaries, and how data is stored. Data structure knowledge is common across everything in software engineering and data engineering — it was stressed as very important for using Bokeh, and the class is expected to know these basics before starting.

With these in hand the transition to Bokeh is easy; without them the learning curve is a little more than average. But these are very basic prerequisites — you do not have to be a data scientist to learn all of this.

Scope: You are not expected to be a data scientist to start with Bokeh. The debugging skill that matters most is reading an error message: locate the line number it points at, read what it says is missing, and check spelling and capitalization — figure and Figure are different names in Python, and a stray uppercase letter is one of the most common beginner errors. Everything else about Bokeh (glyphs, attributes, the workflow) is taught here from zero.

15.4.3 Optional: HTML and CSS

Knowing HTML and stylesheet (CSS) is optional. It is not a must-have, and not knowing it will not stop you from understanding Bokeh. But it gives an added advantage: you may need to embed the HTML output of Bokeh into your own code or pages, and some familiarity with HTML makes that step comfortable.

What "optional" means in practice. Bokeh always produces an HTML page — that is how it delivers interactivity — so you will see HTML whether you know it or not. The knowledge only becomes useful when you modify the page: placing the chart inside an existing site, adjusting the page around it, or styling the surrounding layout with CSS. If you have never written HTML, nothing in this session stops working; the Bokeh calls stay exactly the same. The optional advantage is simply that embedding feels natural instead of mysterious.

The prerequisites, in one line: Python installed, pip available, basic syntax and data structures in your head, and nothing else — next comes the two-command install check that confirms your machine is ready (Section 15.5).

15.5 Installation and Version Check

15.5.1 Installing with pip

Installing Bokeh works exactly like any other Python library:

pip install bokeh

That single command is the whole installation story, the same pattern used for pip install matplotlib and pip install seaborn.

What the command does, step by step. pip looks up bokeh in the package index, downloads the package files, and places them where your Python installation can import them. When the command finishes with a success message, the library is ready — no further configuration. If a newer version already exists on your machine, pip reports it is already satisfied, which is also a fine outcome: it means you can start plotting immediately.

15.5.2 Verifying the Version

To check which version of Bokeh you have, import it and print the version attribute:

import bokeh
print(bokeh.__version__)

Just by saying import bokeh, the library confirms it is present, and the version attribute reveals what you have.

Worked example — the version check in the live demo. The class ran the two lines above on the instructor's machine:

  1. import bokeh — Python loads the installed library; if the package were missing, this line would fail with ModuleNotFoundError.
  2. print(bokeh.__version__) — Python prints the version string stored inside the library.

The installed version printed as 2.4.1, which told the class the machine was ready for core functionality with no extra installation.

Sense-check: an import that succeeds plus a version that prints means install and environment are both healthy — the two-step check is complete.

The website showed a slightly newer version than what was installed, which is a normal situation: many versions are available, and you decide which one you work with. In the live demo, the version shown on the Bokeh website was 2.4.3 — a newer release than the installed 2.4.1. (One number is enough to notice the pattern: the release on the site and the release on your machine are separate decisions, and they rarely need to match.)

Version numbers, decoded. Bokeh uses a three-part version like 2.4.1: the first number (2) is the major version, the second (4) the minor version, and the third (1) the patch level. A change in the minor number (2.3 → 2.4) means new features; a change in the patch number (2.4.1 → 2.4.3) means fixes. None of this changes what you do: install the latest, or keep what you have — the plotting syntax from this session works across these versions, as the class saw when the same demos ran without a single change.

15.5.3 Student Questions and Answers

Q: Can anyone remember what version was shown on the website — 2.1 or 4.1? A: Nobody answered, so the class moved on. The point of the exercise was simply to notice that version numbers differ between releases: your installed version and the latest version on the website will often not match, and that is fine.

The session also paused here to invite any question about Bokeh's usage, properties, or use cases before moving to the next section; the class had none, and the teaching continued.

Recap: pip install bokeh installs the library; import bokeh; print(bokeh.__version__) confirms it and reveals the version (2.4.1 in the demo, with the website showing 2.4.3). Install mismatch with the website is expected and harmless. With the machine confirmed ready, the next section covers the three commands that appear in every Bokeh program (Section 15.6).

15.6 The Core Bokeh Workflow

This section is the procedural heart of the session: the three-command pattern that appears in every Bokeh program, plus the six-step pipeline every visualization follows. If you remember nothing else from this lecture, remember this section — every later demo is just this workflow with a different glyph in the middle.

15.6.1 The Three Always-Used Imports: figure, output_file, show

Every Bokeh plotting session starts with the same import line:

from bokeh.plotting import figure, output_file, show

figure, output_file, and show are the constants that appear in almost every Bokeh code example. Their roles:

  • figure — the function that creates the final output figure. Everything you plot needs a figure first; it acts like a kind of template or raw canvas. Through the figure object you set the title, the tools, and the x-axis and y-axis labels. Once the figure exists, it is up to you what you draw on it — a line chart, a histogram, whatever. You will see it in every example as the object named p.
  • output_fileoptional, but very useful. Here you specify the name of the HTML file your plot will be written to, for example output_file("line_graph.html"). The moment you call show, the output goes into the HTML file you named. If you do not give an output file, Bokeh creates a random HTML file with no meaningful name (in the demo, it landed in the system temp folder). So: name the file if you want it; skip it if you do not care.
  • show — the function that displays the finished Bokeh figure in the browser (or notebook). The typical pattern: you get all the data ready, build the figure with its parameters (line graph, x-axis, y-axis, label), and the last line is show — only then does everything appear on screen.

Why these three, in this shape. Think of the trio as make the page, name the page, open the page. figure builds the empty chart object; output_file decides which page the result lands in; show opens that page. You can run any one of them without the others — figure alone draws nothing visible, output_file alone writes no file, show alone has nothing to display — which is why they always travel together in this exact order.

15.6.2 save and the Default Toolbar

Alongside show there is save, which saves the output to a file instead of displaying it. You will also hear about the renderers, colors, and legends that you configure through the figure and its glyphs. On top of all that, every figure carries the default interactive toolbar from Section 15.1.2 — pan, reset, box zoom, wheel zoom, and save-as-PNG — which arrives on its own, with no extra code. Although the default save format is PNG, you can change the file type in one line and save as JPEG or other formats as well.

show vs save. The distinction is one word: show opens the chart in your browser now; save writes the chart to the output file without opening anything. In practice you use show while developing (you want to look at the chart) and save when generating a chart for someone else (a report pipeline that produces files, not windows). The underlying HTML is identical either way.

15.6.3 The High-Level Steps for Any Plot

The broad pipeline that every visualization follows was laid out like this:

  1. Prepare the data — you need the data with you before anything else.
  2. Decide where the visualization will be rendered — browser, notebook, or an HTML file.
  3. Set up the figure — the figure command, with title, tools, and axis labels.
  4. Connect and pass the data — attach your data to the figure's glyphs.
  5. Decide what layout you want — how charts are arranged (side by side, and so on).
  6. Generate your visualization — usually with show.

These steps become automatic once you write a few examples yourself.

The Tableau bridge. The pipeline is not new: it maps directly onto the Tableau workflow the class already knows. In Tableau you start with a data source (a CSV, a flat file, a database), bring the data in, create individual sheets by dragging and dropping fields, and finally merge everything into dashboards in a logical arrangement. The difference is only in the mechanism — Tableau is drag-and-drop, Bokeh is code. Conceptually the steps are the same: get the data, build a view, arrange views, deliver the result. Everything you already know about thinking in sheets and dashboards carries straight over.

Trace — the pipeline on a tiny chart. Follow the six steps for a chart of two points, (1, 3) and (2, 5):

  1. Prepare the data: x = [1, 2] and y = [3, 5] — two Python lists, ready to go.
  2. Decide where it renders: a named HTML file — output_file("two_points.html").
  3. Set up the figure: p = figure(title="My first plot") — the empty canvas with a title.
  4. Connect the data: p.line(x, y) — attach the two lists to a line glyph.
  5. Decide the layout: one chart, no arrangement needed — the default is fine.
  6. Generate: show(p) — the browser opens two_points.html with a line from (1, 3) to (2, 5), toolbar included.

Sense-check: every step had an output before the next one started — data existed before the glyph consumed it, the file was named before the browser opened, and the result was the expected two-point line.

15.6.4 Preparing the Data

When you prepare data for Bokeh you end up using lists, arrays, or data frames as your building blocks. Lists and numpy arrays feed simple examples directly; data frames are the natural container when you plot data from a table (as in the Iris example in Section 15.14). This is also where the optional output_file name matters: give the file name as something.html and the plot opens in the browser with that name; skip it and Bokeh picks a random name.

Which container to pick. A Python list ([1, 2, 3]) is the fastest way to try a glyph. A numpy array is the same idea with math attached — you generate 100 numbers in one call. A pandas data frame is a table with named columns, and it is what you reach for when your data is already in a spreadsheet or a database. Bokeh accepts all three, and the glyph call looks identical — p.line(x, y) does not care whether x is a list or a column, which is why the demos switch between them without ceremony.

A note on the workflow's end. The pipeline's last step — generate — is where show or save executes, and it is also where the toolbar from Section 15.1.2 comes alive. The full loop, once automatic, is the same shape for every chart in this lecture: data → figure → glyph → show.

15.7 Bokeh vs Matplotlib vs Seaborn

The class spent a dedicated block comparing Bokeh with the two libraries covered earlier, parameter by parameter. The comparison is worth keeping in full because it is always good to keep reminding ourselves when to use which library.

15.7.1 Purpose and Focus

  • Matplotlib is primarily static, publication-quality visualization. It gives you a lot of control, but its primary focus is static 2D plots — the kind of diagrams you put in a publication. It can still make 3D plots, but the main purpose is static 2D plotting.
  • Seaborn is built on top of Matplotlib (covered in the previous class) and is very specific to creating beautiful statistical graphs. Its whole purpose and focus is the data science community — anyone looking for a statistical graph opts for Seaborn.
  • Bokeh is mainly for interactive, web-based visualization. The focus is on the interactivity part: building dynamic dashboards and applications. You can embed several graphs next to each other the way dashboards in Tableau do — remember dragging one graph and keeping it left or right of another. Tableau does that by drag-and-drop; Bokeh does it with code, but in principle you reach the same output, and these things are free.

So the summary line: Matplotlib for static, customized, low-level-control plots; Seaborn for statistical visualization and quick creation; Bokeh for interactivity, web-based visualization, and dynamic dashboards.

15.7.2 Ease of Use and Syntax

  • Matplotlib requires more code. Because you customize each and every bit yourself, you end up writing more code and you really need to be on top of the syntax.
  • Seaborn offers a high-level API. You can pass many parameters and create plots much more easily than in Matplotlib, and quickly. Its syntax and purpose fit exploratory data analysis — exploring things with statistical visualization.
  • Bokeh also offers a high-level API, and the code is comparatively the least of the three. By calling one or two lines and passing parameters, you can create basic charts with very minimal code. It is easy and much more user-friendly, especially when it comes to adding interactivity.

15.7.3 Interactivity and Deployment

This one is a no-brainer:

  • Matplotlib has limited interactivity; when you deploy, the result is static images.
  • Seaborn has limited interactivity compared to Bokeh, and its output is also static — interactivity is not its primary focus.
  • Bokeh produces highly interactive visualization on a web page — hover, pan, zoom, select. It generates HTML and JavaScript-based visualization that you can deploy on a web page or integrate with your web pages. The other two create static images; Bokeh creates a page.

15.7.4 Use Cases

  • Choose Matplotlib when you need something static — publication material, basic fundamental 2D graphs for scientific publication.
  • Choose Seaborn when you are hardcore into data science or statistical visualization — violin plots, box plots, quartiles, and those sophisticated statistical graphs.
  • Choose Bokeh depending on what your ask is — the interactive, web-based, dashboard side.

15.7.5 Integration and Ecosystem

  • Matplotlib is integrated with the wider Python ecosystem and can integrate with libraries like Seaborn.
  • Seaborn is built on top of Matplotlib, so it integrates seamlessly — a no-brainer.
  • Bokeh goes one level beyond: it integrates with the popular data manipulation libraries Pandas and NumPy, supports integration with web pages, and goes even further — you can combine it with web frameworks like Flask and blend Bokeh charts with other web pages.
Dimension Matplotlib Seaborn Bokeh
Core focus Static 2D, publication-quality plots Statistical graphs, built on Matplotlib Interactive, web-based visualization
Code needed Most — you customize everything Little — high-level API, quick Least — one or two lines for basic charts
Interactivity Limited Limited Native: hover, pan, zoom, select
Output Static image (PNG/PDF) Static image HTML + JavaScript page
Typical user Scientists writing papers Data scientists exploring data Teams building dashboards and web apps
Ecosystem Whole Python ecosystem Matplotlib + Pandas Pandas, NumPy, web frameworks like Flask

When to pick which. If the chart will be printed or published, reach for Matplotlib; if you are exploring statistics quickly, reach for Seaborn; if someone will click on the chart in a browser, reach for Bokeh.

15.7.6 The Key Intuition: Not One Library per Chart

A key clarification, because students often misread the comparison: it is not that you can only make one type of chart in one library. All these libraries can create broadly most of the common plots — if you need a scatter plot, you can go to Matplotlib; you are not locked out. What differs is the nature of the offering: the interactivity of Bokeh, the statistical nature of Seaborn, and the primarily 2D static nature of Matplotlib. That is the criterion you choose on, not "which chart belongs to which library."

Pitfall — the "one chart, one library" myth. A beginner who misreads the comparison wastes time memorizing which library "owns" each chart type. The chart types overlap almost completely; the deciding question is what the chart must do for its audience. Scatter plot for a paper → Matplotlib; scatter plot with trend statistics → Seaborn; scatter plot on a live dashboard → Bokeh. Same chart, three libraries, chosen by purpose, not by chart type.

Exam note: the when-to-use-which-library distinction is exactly the kind of comparison worth studying — it was repeated for emphasis. The deciding dimension is purpose and focus (static vs statistical vs interactive), and Bokeh's edge is interactivity and web deployment; the other libraries create static images.

15.8 Bokeh Interface Layers

15.8.1 Model, Plotting, and Chart

Bokeh's API is organized in layers, from low level to high level, and it is worth knowing the stack even if you never touch the bottom:

  • Model (low level) — you first choose the different models. This layer provides the flexibility. It is the raw object layer of Bokeh.
  • Plotting (mid level) — on top of models sits plotting, the layer that gets the interface ready for plotting anything. This is where the plotting module (the figure import from Section 15.6.1) lives.
  • Chart (high level) — on top of plotting sits the chart layer, where the end user decides the final chart: "I want a line chart", "I want a scatter plot". This is the level you call with bokeh.chart.<something>.

So the flow is bottom-up: model, then plotting, then chart.

Why layers exist. Each layer is a different level of control. The bottom (model) layer is the most flexible and the most verbose: it exposes the raw building blocks of every chart — axes, grids, glyphs — and lets you assemble them by hand. The middle (plotting) layer hides most of that plumbing behind the figure command and its glyph methods, which is the level this session actually uses. The top (chart) layer hides even more: you name the chart you want and Bokeh fills in the defaults. Think of it as cooking with increasing convenience: raw ingredients (model), a recipe with measurements (plotting), a restaurant menu (chart). All three describe the same plot; they differ in how much control and how much typing you give up.

Visual intuition. Picture the stack as three floors of a building. The ground floor (model) holds the machinery — pipes, wiring, load-bearing walls — invisible in normal use but responsible for everything above. The middle floor (plotting) is where the rooms are arranged into a layout. The top floor (chart) is where the furniture is placed. Most people live their whole lives on the top two floors; the ground floor is for the builders and the curious.

15.8.2 How Bokeh Runs in the Browser

Under the hood there are two halves: bokeh.js and the bokeh Python library. Bokeh.js runs in the browser and renders JSON objects; the Python library runs in your code and produces those JSON objects. The Python side builds the JSON description of the plot, and the JavaScript side renders it — that is broadly how a Bokeh visualization reaches the screen.

The handoff, step by step. Your Python script calls figure and the glyph methods; each call adds entries to an in-memory description of the plot. When you call show (or save), Bokeh serializes that description into JSON — a text format of labeled data — and embeds it in the HTML page along with the bokeh.js library. When the browser opens the page, bokeh.js reads the JSON and draws the plot: axes, glyphs, toolbar, tooltips. From then on, every interaction (pan, zoom, hover) is handled entirely in the browser by bokeh.js — the Python process is no longer involved. That two-process split is exactly why the interactivity is so smooth: the chart's behavior lives next to the reader, not on a distant server.

The technical stack is not something to memorize — it is for the curious and technical-minded. What you should know is the syntax at the plotting level; the internals are context, not exam material.

Exam note: the interface layers are context, not exam material — there is no need to memorize them. What counts is knowing the plotting-level syntax: the figure + glyph + show pattern from Section 15.6, and the fact that the layers exist in a bottom-up order (model → plotting → chart).

15.9 Glyphs — The Building Blocks

15.9.1 Definition: The Building Blocks of Bokeh

Glyphs are the building blocks of Bokeh: the graphical elements that turn data into visualization form. They are the fundamental shapes and symbols used to make data visible — the line for a trend, the marker for a scatter point, the rectangle for a bar. The name "glyph" is simply what Bokeh calls these controls; the same ideas appear in other libraries under other names, but Bokeh's glyphs are special because they can be layered on top of each other on the same figure. You can draw one series as a plain line, another as squares, another as circles — all on the same chart — and combine them into beautiful visualizations. That ability to stack components is why Bokeh calls them building blocks.

Why "building block" is the right word. A building is not one slab of concrete; it is walls, floors, windows, and doors assembled into a structure. A Bokeh figure works the same way: every visual element — every line, marker, bar, and rectangle — is one glyph, and the chart is the assembly of the glyphs you choose. Because each glyph is an independent object, you can add, remove, or restyle one element without touching the others. That modularity is what makes the "one word changes the chart" trick of the demos work: p.circle and p.square are two glyphs wearing the same data.

15.9.2 The Pizza Analogy

To make glyphs concrete, the class was taught with a food analogy that was reused throughout the session: think of a pizza.

  • Glyphs are the toppings. A circle for a scatter plot, lines for trends, squares for a bar chart — these are the regular toppings that help you build the figure. You can put many toppings on the same pizza: a bit of circle, a bit of square, a bit of wedges, and together they make the visual interesting.
  • Data is the flavor. Data controls the sizes and dimensions of the pizza and everything on top of it. If you have a variable called size for a particular marker, that data makes the marker bigger or smaller.

Combining toppings and flavor is the whole game: choose the shapes (glyphs), control their sizes from the data, decide their coloring, and stack them — and you can make the graph as interesting as you like.

Where the analogy breaks. A pizza is finished when it leaves the kitchen; a Bokeh chart keeps living — the reader can zoom, pan, and hover over the finished product, and the "toppings" can be swapped while the pizza is still on the table. The analogy captures the building side (choose, size, stack); the interactivity is the part that no food analogy can reach.

15.9.3 Types of Glyphs

The main glyph families are:

  • Markers — circles, squares, triangles, or any customized symbol. Markers were already met in the Seaborn class; there, you changed markers by passing one parameter. Here the same idea comes with interactivity, which is why the figure-calling syntax is slightly different.
  • Lines — single line, step line, multiple lines, lines with breaks between points, stacked lines.
  • Bars and rectangles — vertical bars, horizontal bars, stacked bars, and arbitrary rectangles (also the basis of histograms, via quad).

How the families map to charts. Each family is a shape vocabulary: markers place individual points (scatter), lines connect points in order (trend), bars and rectangles fill area between boundaries (comparison, distribution). A histogram is the surprise member of the family: it looks like a bar chart, but it is built from the rectangle glyph quad, because each histogram bin is just a rectangle with its own top, bottom, left, and right edges. Knowing the family names helps later: when a demo introduces p.vbar, p.quad, or p.multi_line, you already know which family it belongs to and what kind of chart it will draw.

15.9.4 Attributes: Customizing a Glyph

Once you choose a glyph, you pass attributes to control its appearance. For a circle you might say: make it red, set the line width, set the transparency. Size, color, line width, and alpha (transparency) were the parameters listed as the ones you will commonly pass. Every glyph accepts this kind of customization, and these attributes become part of your dynamic visualization.

The attributes, named and numbered. Size (how big the glyph is — for a circle, its radius in screen pixels), color (a named color like "navy" or a hex code), line width (how thick the glyph's outline or the line's stroke is), and alpha (transparency, on a scale from 0 = fully invisible to 1 = fully solid). These four show up in nearly every demo that follows, and they are passed directly inside the glyph call: p.circle(x, y, size=20, color="navy", alpha=0.5). The attribute names travel with the glyph, which is why "one word changes the chart" also means "one parameter changes the look".

15.9.5 Column Data Source (Preview)

There is one more concept that connects glyphs to data: the ColumnDataSource. When you connect with a database, the ColumnDataSource is what links the data directly to the x and y coordinates — the plot pulls data straight from the table and you bind columns to the glyph. This was previewed but explicitly deferred: how glyphs and the ColumnDataSource work together is covered in the next session, when data integration with Bokeh is taught.

Why it deserves a mention now. So far every demo passes data directly into the glyph call (p.line(x, y)). That works, but it loses the connection between the chart and the table the data came from. The ColumnDataSource is the piece that rebuilds that connection: it wraps a data frame or dictionary, and the glyph reads its coordinates from named columns. Previewing the name now means tomorrow's session starts from a familiar anchor.

Pitfalls around glyphs.

  • Confusing the glyph with the figure. The figure is the canvas; the glyph is one drawing on it. You call p.circle(...), not figure.circle on a fresh figure every time — create one figure, then stack many glyphs on it.
  • Expecting every glyph to accept every attribute. Markers take size; lines take line_width; bars take top or right and width. Passing a marker attribute to a bar is the classic error — the parameter that makes sense depends on the glyph family.
  • Forgetting that attributes belong to the glyph call. Style set inside the glyph call (p.line(x, y, color="firebrick")) affects that glyph only; the figure's own settings (title, axis labels) are separate.

Recap: Glyphs are Bokeh's building blocks — markers, lines, and bars/rectangles — placed on a figure like toppings on a pizza, with data as the flavor controlling size and dimension, and attributes (size, color, line width, alpha) as the styling. The next section puts the first glyph to work in a real chart (Section 15.10).

15.10 Worked Example: The First Line Graph (Sine Wave)

15.10.1 The Code, Step by Step

The first live example built a sine wave with just five or six lines. It was chosen not for the mathematics but to show how little code a real Bokeh chart needs. The structure, decoded line by line:

  1. Imports — the standard line: from bokeh.plotting import figure, output_file, show. The example also imported numpy because it needed a little numbering — numpy is the full mathematics library where you can get sine, cosine, and all mathematical functions with a single call. (Full numpy coverage is not in scope for this class; it was used only to generate the demo data.)
  2. Generate the data — random numbers were passed into x, and y was computed as the sine of the x values, using the math constant from numpy:

where (a lowercase x) is a set of random numbers and (a lowercase y) is the sine of each value — the sine function takes an angle as its input and returns a number between and . The verbal description that accompanied the formula: "it is passing the x parameter to a sine wave... it is generating a random number in x axis and it is giving y as the sine of that value, so that it can create a sine wave." The mathematics was not the lesson — it was simply a way to produce an interesting curve.

  1. Output fileoutput_file("sine_wave.html"): "Mr. Bokeh, give us whatever output you generate in a file with this name."
  2. Create the figurep = figure(...) with the title and axis labels passed in. This is where p first appears: p is an object of the figure class, created by calling the figure function. From then on, p.<something> means "from this figure, I want <something>."
  3. Draw the line glyphp.line(...): here the line glyph is called with the x and y data and a legend name. This line is the glyph line — the point where the glyph concept enters the code.
  4. Showshow(p) renders the figure in the browser.

Why this order is the only order. Each line hands its output to the next: without the imports nothing else can be named; without data there is nothing to draw; without a figure there is nowhere to draw; without the glyph there is no chart; and show must be last because it displays whatever has been assembled so far. Rearranging the steps is the fastest way to produce an error message — and reading that message, per Section 15.4, is how you find which step was skipped.

15.10.2 The Output and the Interactive Toolbar

Worked example — the sine wave demo, with real numbers. The demo ran this structure (reconstructed from the lecture's description):

from bokeh.plotting import figure, output_file, show
import numpy as np

x = np.random.uniform(0, 2 * np.pi, 100)   # 100 random angles between 0 and 2*pi
y = np.sin(x)                              # sine of each angle

output_file("sine_wave.html")
p = figure(title="Sine Wave", x_axis_label="x", y_axis_label="sin(x)")
p.line(x, y, legend_label="sine")
show(p)

Walking through the numbers: x holds random angles spread across one full circle of radians (about 6.28). For each angle, returns its height between and : at , ; at , ; at , ; at , ; back at , . Because the x values are random rather than evenly spaced, the drawn line is a jittered, scribble-like version of the smooth sine curve — the point is the curve's shape, not the exact positions.

Running the code produced sine_wave.html — a sine wave with the default toolbar already active: move/pan the graph, reset to the original shape, box-zoom into any selected area (including zooming deeper into an already-zoomed region), wheel zoom with the mouse scroll, and save to PNG. All of that came from calling Bokeh; no interactivity code was written.

Sense-check: the plot's y-values swing between and exactly as the sine formula requires, and the zoom/pan/save tools all respond without any code — the demo did what five lines promised.

The takeaway: a very simple line graph, and the interactivity arrived on its own. This is the pattern in interactive reporting — a live chart embedded in a page that viewers can pan and zoom themselves, instead of a fixed screenshot. A financial site's intraday price chart, a monitoring page's live latency graph, a dashboard's real-time sensor readout — all are the same "small code, living chart" recipe.

Visual intuition. Picture the plot window: x runs left to right along the bottom axis (labeled x), sin(x) runs from to up the left axis (labeled sin(x)). The curve crosses the horizontal center at roughly regular intervals — the zeros of the sine — and peaks near the top and dips near the bottom. Zoom in with box zoom and the curve's local wiggles spread out across the full window; reset and the whole wave snaps back. One glance tells you the shape is a wave — which is the entire point of choosing sine data for the demo.

15.10.3 Deprecation Warnings: How the API Evolves

During the demo the code produced deprecation warnings: instead of the label argument, newer Bokeh versions want the more advanced commands legend_label or legend_field. The explanation is worth keeping: whenever there is an upgrade in the documentation, this is how the commands change — Bokeh tells you the new name, and you update your code next time. The examples were updated for the newer syntax afterward. This is normal library maintenance, not an error in your approach.

What a deprecation warning actually is. A deprecation warning is the library's polite way of saying "this command still works today, but it will be removed in a future release — switch to this new name." It is a forecast, not a failure: your code ran correctly despite the message. The pattern to learn is the pattern of the warning itself — when you see one, (1) read which old name it flags, (2) read which new name it suggests, (3) update your call, and (4) move on. The one-time switch from label to legend_label/legend_field in this session is a live example of that loop.

Pitfalls from this demo.

  • Panicking at a deprecation warning. The warning is the library helping you; your chart rendered fine. Update the name it suggests and the warning disappears.
  • Memorizing the demo code line by line. This is the point where the professor stopped the class: do not get pressurized by the volume of code — these code details, the exact glyph commands and parameters, will not be asked on the exam. The demo's job was to show what Bokeh can do, not to become a memorization burden.
  • Forgetting that p is a figure object. Every p.<something> call is an instruction to that one figure; recreating the figure mid-script throws away the chart built so far.

Exam note: it was explicitly stated that this kind of code — the exact glyph commands and parameters — will not be asked on the exam. The demo code was shared to show what Bokeh can do, not to be memorized. What you should carry forward is the concept flow: data → figure → line glyph → show, and the fact that the toolbar interactivity arrives by default.

15.11 Worked Examples: Scatter Markers

15.11.1 The Circle Marker Demo

The second demo showed a scatter chart with circle markers. The code again opened with the standard figure/output_file/show imports; the output file was named line.html for this run, and the figure was created with width 400 and height 400p = figure(width=400, height=400). Then the circle glyph was called:

p.circle(x, y, size=..., color="navy")

The x and y parameters were small sets of points — (1, 6), (2, 7), and (3, 2) — plotted as navy circles. With show, the plot rendered in line.html with all the default interactive features — zoom into an area, reset, scroll in and out, save.

The anatomy of the demo, decoded line by line: the standard import line; output_file("line.html") to name the output; the figure created with a width and height; then, instead of p.line(...) as in the previous example, p.circle(...) with the data and the size and color parameters — the glyph line again.

Worked example — the circle marker demo, with real numbers. The demo's scatter data, read from the three (x, y) pairs:

Point x y where it sits on the chart
1 1 6 near the top-left, since the y-axis rises to at least 7
2 2 7 topmost point — highest y of the three
3 3 2 bottom-right — lowest y

The code shape:

from bokeh.plotting import figure, output_file, show

output_file("line.html")
p = figure(width=400, height=400)
p.circle([1, 2, 3], [6, 7, 2], size=20, color="navy")
show(p)

Reading the lists: the first list holds the three x coordinates (1, 2, 3), the second the three y coordinates (6, 7, 2), matched position by position — so point 1 is (1, 6), point 2 is (2, 7), point 3 is (3, 2). size=20 makes each circle 20 pixels across, and color="navy" fills them dark blue.

Sense-check: three inputs produced three circles at the expected positions — the x list and y list pair up in order, so (1, 6), (2, 7), and (3, 2) each got one circle.

15.11.2 The Square Marker Demo

The next demo changed exactly one word: instead of p.circle, the code called p.square with the same points. The output file was named square.html, and the plot rendered square markers in place of circles. Nothing else changed — no need to re-initiate anything — and the interactivity was identical. This "one word changes the whole chart" pattern is the heart of the glyph approach.

Worked example — the square and plus demos, side by side. The professor's point was the diff — one word:

p.circle([1, 2, 3], [6, 7, 2], size=20, color="navy")   # circles
p.square([1, 2, 3], [6, 7, 2], size=20, color="navy")   # squares
p.plus([1, 2, 3], [6, 7, 2], size=20, color="navy")     # plus signs

Same figure size, same data, same styling attributes — only the method name changes. The chart itself changes completely: round marks become square blocks, then become plus shapes. The data and the figure needed no other adjustment because the glyph is just a different shape vocabulary for the same coordinates.

Sense-check: since only the marker shape changed, the three charts must show identical positions and colors — and they did, which proves the glyph name is the only thing that distinguishes a circle, square, or plus chart.

Returning after the break, one more combination was shown: the previous square code was edited so that instead of p.square it called p.plus. Running it produced plus-shaped markers. The lesson: you decide what kind of marker you want, and by calling the matching function — just one word — Bokeh does the rest.

15.11.3 The Marker Catalog

Bokeh ships with many predefined markers, and the list is surprising when you first see it. A catalog of marker types and their callable functions was shown: circle, square, cross, diamond, and many combination-permutation variants — diamond cross, diamond dot, circle cross, circle dot, circle x, circle y, square cross, and so on. To use one you simply call p.<markername> (for example, p.circle_cross(...) or p.diamond(...)). All of these are predefined in the library; you decide which one fits your data, and the source list is documented on the Bokeh website. That is the power of these libraries — everything is predefined, you just call it.

Why so many markers exist. Each marker is a compact visual code: on a chart with several series drawn together, you need shapes that stay distinguishable when colors are printed in black and white or viewed by someone with color blindness. The circle-cross, circle-dot, circle-x, circle-y variants are not random noise — they are small, readable increments on the same base shape, so a dense scatter with four series can use four easy-to-distinguish marks without ever changing color. When you pick a marker, you are choosing how easy it will be for the reader to tell series apart.

Pitfall — the catalog is for choosing, not memorizing. Nobody is expected to hold thirty marker names in memory; the pattern to internalize is that any marker has a p.<name>(...) call and that the website lists them all. If you forget a name, the gallery or the marker list reminds you in seconds.

Recap: Scatter markers are glyphs chosen by method name — p.circle, p.square, p.plus, and a large predefined catalog (p.circle_cross, p.diamond, ...) — with the same data and attributes working across all of them. One word changes the whole chart. Next, the line family shows the same one-word trick applied to connected lines (Section 15.12).

15.12 Worked Examples: The Line Glyph Family

After the scatter markers, the class worked through the line glyph family — several line charts built by changing one function name, exactly like the marker demos.

15.12.1 Simple Line

p.line(...) with x values, y values, and a line width creates a plain continuous line chart. The demo output went to line.html and showed a simple line connecting the given points. This is the same p.line call from the sine wave example — the common, familiar form. (Labels and tooltips were deliberately not covered in this session; the goal was the bare-bones minimum functionality.)

Worked example — the simple line. Give the line glyph two lists of numbers and a stroke thickness:

p.line(x, y, line_width=2)

With x = [1, 2, 3, 4] and y = [1, 4, 2, 5], the glyph places the four points (1, 1), (2, 4), (3, 2), (4, 5) and connects them in order with a line 2 pixels thick. The result is a continuous zigzag from left to right — no gaps, because every x position has a y value.

Sense-check: four points, one continuous path — the number of y values equals the number of x values, so the line has no missing segments.

15.12.2 Step Line

Changing p.line to p.step — everything else identical, same parameters, same line width, same output file — produced a step line: a line that stays flat and jumps to each next value instead of sloping toward it. One word changed the whole visual.

Intuition — stairs, not slopes. Think of a normal line as a smooth ramp and a step line as a staircase: the line holds its height flat, then jumps vertically to the next height at each new x. The flat sections are the "steps" and the vertical jumps are the risers. That shape is the natural way to show values that stay constant between events — a price that held all day, a stock level that changed at one moment, a signal that switched between on and off. Same data, a different story about how the value changes between points.

15.12.3 Multiple Lines

Calling p.multi_line(...) drew several separate lines in one call. In the demo, passing two sets of x-y pairs created two lines, rendered into patch.html with colors passed along with the data. The general pattern: p.line makes a simple line, p.step makes a step line, p.multi_line makes multiple lines — these are the syntaxes, and you can try the coloring and line-width combinations yourself, since the demo's aim was to show the glyph commands, not every permutation of styling.

Worked example — multi_line with two series. The demo passed two x-y pairs at once:

p.multi_line([[1, 2, 3], [1, 2, 3]], [[3, 4, 2], [1, 5, 2]], color=["firebrick", "navy"])

The outer lists pair up: the first line connects (1, 3), (2, 4), (3, 2) in firebrick; the second connects (1, 1), (2, 5), (3, 2) in navy. Both lines share the same x values, which is exactly the situation a multi-line chart is built for — several series over one common axis.

Sense-check: two inner pairs of lists produced exactly two lines, each with its own color — the number of line segments equals the number of (x-list, y-list) pairs.

15.12.4 Missing Point

The missing-point example showed a line with a deliberate gap. One value in the data was left empty — it is "like a null in any other thing," as the explanation put it. The data list contained values like 1, 3, 1, 2, 3, 4, 6, 7, 2, 4, 5, and in one position no number was passed at all. With p.line, Bokeh drew the line but left a visible gap exactly at that missing point — a useful trick when your data has holes.

Worked example — the missing point, with the demo's data. The demo's y list, read from the lecture, was:

y = [1, 3, 1, None, 3, 4, 6, 7, 2, 4, 5]

Count the positions: the 4th value is None — no number at all, the same as a null in a database or an empty cell in a spreadsheet. Bokeh treats it like the professor described: there is simply no point at x-position 4, so the line is drawn through positions 1–3, stops, and resumes at position 5. On screen, that shows as a visible gap in the line at the missing x — the chart honestly reports "no data here" instead of inventing a value.

Sense-check: the gap appears at exactly one x position (the null), and the rest of the line is continuous — the null was honored, not filled in.

Why this matters in real data. Real datasets have holes — a sensor offline for an hour, a survey question skipped, a database row never written. A library that silently bridges the gap would fabricate a value and mislead the reader; a library that draws the gap shows the truth. Charts that respect missing values are a basic honesty requirement for analytical work.

15.12.5 Stacked Lines

The last line example used p.vline_stack to draw vertical lines in a stacked manner: two variables, Y1 and Y2, over a shared X, each drawn on top of the other. You could easily draw one line, add another with p.hline_stack or another parameter on top of it, and keep adding what you want onto the figure — many combinations and permutations, horizontal or vertical, multiple lines on top of each other. Remember the pizza: the figure is the pizza base, and each glyph is another topping you can add.

Stacked vs multi-line. multi_line draws several independent lines side by side on the same axes. The stacked variants build a different geometry: vertical stacking (vline_stack) piles series upward at each x — like a stack of layers on a column chart — while the horizontal variant (hline_stack) accumulates along the x direction. Stacking is the right choice when the total matters as much as the parts, because each layer's distance from the baseline shows its contribution to the running sum.

Pitfalls from the line family.

  • Forgetting that y and x must match in length. A missing y value that is not marked as null (a shorter list, or a list with a wrong count) shifts every later point one position and silently redraws the whole line. Mark holes with null, not by deleting values.
  • Expecting p.line to skip nulls gracefully. It does not — that is what the gap in 15.12.4 was about. If you want the line to jump across the hole, fill or interpolate the value first; if you want the hole shown, keep the null.
  • Overlaying without stacking. Adding two plain p.line calls over the same data draws lines that cross; when the story is "how much each part contributes to a total," the stacked glyph is the intended tool.

Recap: The line family is one-word-deep: p.line (continuous), p.step (flat with jumps), p.multi_line (several lines in one call), null values create honest gaps, and p.vline_stack / p.hline_stack stack series on top of each other. Each line glyph is another topping on the pizza base of the figure. Next, the bar and rectangle family (Section 15.13).

15.13 Worked Examples: Bar and Rectangle Glyphs

15.13.1 Vertical Bar (vbar)

The bar glyphs come in vertical and horizontal forms. p.vbar creates a vertical bar chart: you pass the x positions, the bar heights (the "top"), a width, and colors. In the demo the bars were colored firebrick — a dark red — and each bar's height reflected its value. All the zooming and panning works on bars just like on lines.

Worked example — a vertical bar chart. The demo's essentials:

p.vbar(x=[1, 2, 3], top=[4, 7, 2], width=0.5, color="firebrick")

Each x position gets one bar; top says where that bar's top edge stops on the y-axis (the bottom stays at 0), and width sets the bar's thickness along the x-axis. So bar 1 rises to height 4, bar 2 to height 7, bar 3 to height 2, all 0.5 wide, all firebrick red. The height of each bar is the value it reports — a bar of height 7 is 3.5 times as tall as a bar of height 2.

Sense-check: three top values produced three bars with exactly those heights — top is the y-coordinate where the bar stops, not its length from somewhere else.

15.13.2 Horizontal Bar (hbar)

Changing the function name from vbar to p.hbar — one alphabet changes the direction and the whole chart type. For a vertical bar you tell Bokeh how tall the bar should be by setting top; for a horizontal bar you instead set right — where the bar ends on the right side is the value. The demo's horizontal bars showed lengths around 1.2 for the first bar and around 2.5 for the second.

Worked example — the horizontal bar demo. The vertical bar said "stop at this height"; the horizontal bar says "stop at this right edge":

p.hbar(y=[1, 2], right=[1.2, 2.5], height=0.4)

Bar 1 sits at y-position 1 and extends from the left edge to — its length is 1.2. Bar 2 sits at y-position 2 and extends to — its length is 2.5, roughly twice the first. The height parameter (the bar's thickness along the y-axis) replaces width from the vertical form.

Sense-check: the bar's length equals its right value, so the second bar (2.5) is about twice as long as the first (1.2) — lengths and values match one to one.

15.13.3 Stacked Bars

By changing one word you can also create a stacked bar chart — in the demo, a horizontal stacked bar: several variables (X1, X2, and more) each contributing a segment, stacked end to end inside one bar. The key message of the bar section: look at how the values change by just changing the glyph function — line, bar, stack — these are all glyphs you can call with one parameter, and each one produces a different chart.

How a stacked bar works. A single bar now represents a total, split into segments by variable. For a horizontal stacked bar built from variables X1 and X2, each category's bar lays X1's value as the first segment from the left, then X2's value as the next segment starting where X1 ended. The whole bar's length is the sum , and each segment's length shows that variable's share. That makes stacked bars the tool for "how is the total split up?" — one look tells you both the total and its composition.

15.13.4 Rectangles (quad)

Finally, quad creates rectangles: you pass top, bottom, left, and right coordinates, and Bokeh draws the rectangles between them. This is the same quad glyph that powers the histogram (Section 15.15.3). The rectangle demo completed the bar-and-rectangle family, and the wrap-up: all the syntax and the full list of functions are beautifully explained on the Bokeh portal, so there is no need to worry — a full multi-hour class could be spent on the combination-permutations of bar and rectangle charts alone. These demos are very small examples; the vastness of what the library offers is real.

Worked example — quad, the most flexible rectangle. Instead of a value and a direction, quad takes four edges:

p.quad(top=[6, 4], bottom=[2, 1], left=[0, 3], right=[2.5, 4.5])

The first rectangle is bounded by , , , — a block from height 2 to height 6, spanning x from 0 to 2.5. The second spans heights 1 to 4 and x from 3 to 4.5. Because all four edges are explicit, quad can draw rectangles anywhere — floating boxes that start above the baseline, or the touching, side-by-side bins of a histogram.

Sense-check: two sets of four edge values produced two rectangles, each exactly inside its stated bounds — quad is just "draw a rectangle between these four lines."

Where the bar family lives in industry. Bar and stacked-bar charts are the workhorses of operational dashboards — a sales dashboard showing revenue per region, a warehouse panel splitting stock by category, a budget screen comparing planned vs actual. They answer "how much" instantly, and their stacked forms answer "how is it composed." Staying in touch with these technologies in your career is worthwhile: the bar glyphs in any modern tool trace back to the same four-edge geometry shown here.

Recap: The bar-and-rectangle family: p.vbar (top = height, with width and color), p.hbar (right = length), stacked bars (variables like X1, X2 lay segments end to end), and p.quad (four explicit edges: top, bottom, left, right) — the same quad that builds histograms. One word or one alphabet flips the whole chart type. Next: the first real dataset, the Iris scatter (Section 15.14).

15.14 Worked Example: Scatter Plot with the Iris Dataset

15.14.1 The Code Walkthrough

This example was the first to plot data from a real dataset, and it was walked through line by line so the class could learn to read Bokeh code:

  1. Importsfrom bokeh.plotting import figure, show — note: no output_file this time. figure is for creating plots, show for displaying them.
  2. Get the data — every Python library ships predefined sample data sources, and this example used the Iris dataset (from bokeh.sampledata.iris import flowers), the famous flower species database that is very popular for examples. It exists specifically for demonstration purposes.
  3. Create the figure — the figure object is created and given the alias p. In all the examples you have seen the same pattern: create a figure, alias it as p, then say p.<this> and p.<that>.
  4. Add the scatter plot — a circle glyph is added: p.circle(...), the same glyph from Section 15.11. Two fields from the dataset are used — sepal length as the x axis and sepal width as the y axis — passed as the glyph's x and y parameters. (The spoken names "sample length" / "sample width" and "sepple length" are the sepal measurements of the Iris flowers.)
  5. Customize the glyph — size, color, and alpha (transparency) are passed as parameters, and the legend is positioned at top left.
  6. Showshow generates the plot in the browser: a scatter of all the flowers, with the length and width values coming directly from the database.

Worked example — the Iris scatter, with the data flow made explicit. The demo's structure:

from bokeh.plotting import figure, show
from bokeh.sampledata.iris import flowers

p = figure(title="Iris Scatter", x_axis_label="sepal_length", y_axis_label="sepal_width")
p.circle(flowers["sepal_length"], flowers["sepal_width"],
         size=15, color="navy", alpha=0.5,
         legend_label="Iris flowers")
p.legend.location = "top_left"
show(p)

The data flow, step by step: flowers is a table (a data frame) of 150 iris flowers, one row per flower, with columns for sepal length, sepal width, petal length, petal width, and species. The glyph call pulls the whole sepal_length column as x and the whole sepal_width column as y — so each of the 150 rows becomes one circle. size=15 fixes every circle's diameter, color="navy" fills them dark blue, and alpha=0.5 makes them half-transparent — which matters here, because 150 points can overlap, and translucency lets overlapping points show up as a darker cluster instead of hiding each other. The legend is anchored to the top-left corner.

Sense-check: 150 rows in, 150 circles out — the column of lengths and the column of widths pair up row by row, and every flower appears exactly once.

The glyph line in this whole code was the p.circle(...) call: it selected the glyph, pointed x and y at the data fields, and customized the appearance with the attribute parameters — the "pizza" customization in action. "In my pizza I want a big piece of mushroom" — that is size=20; this is where you change the properties of the glyph.

About the dataset. The Iris dataset is the classic hello-world of data science: 150 flowers from three species of iris (setosa, versicolor, and virginica), each measured on four parts — sepal length, sepal width, petal length, petal width. It appears in every Python plotting library precisely because it is small, real, and famous: a scatter of sepal length against sepal width already shows the species parting into visible clusters. Its role here is the same as in the wider ecosystem — a ready-made demonstration that shows a library's glyphs against real tabular data.

Visual intuition. Picture the scatter: the x-axis (sepal length) runs left to right, the y-axis (sepal width) runs bottom to top. Most points gather in the middle-left of the window; some form a looser, higher cloud toward the right. Overlapping points show as darker navy patches because of the half alpha — the transparency is doing visible work, not just decoration. Zoom into any cluster with box zoom and the points separate; hover would reveal exact values (tooltips were not the focus this session). The one-glance takeaway: two measurements of the same flowers already spread into recognizable groups.

15.14.2 What Happens Without output_file

Because output_file was not given this time, Bokeh still showed the plot in the browser — it simply kept the generated HTML in the system's temp folder with a random name. So output_file is optional for display; it only matters when you want a meaningful, stable file name (the file is still created either way). The zooming, scrolling, and saving all worked exactly as before.

Why the demo skipped it on purpose. Dropping output_file from the import line made the point of Section 15.6.1 concrete: the file name is a convenience, not a requirement. Bokeh's fallback is to generate a temporary HTML file with a meaningless name in the operating system's temp folder and open it — fine for exploration, bad when you need to find or share the chart later. That is exactly why the recommended habit is output_file("a_meaningful_name.html") in anything you intend to keep.

Pitfalls from the Iris example.

  • Typing the column names wrong. The glyph reads the data frame's columns by name — flowers["sepal_length"] fails if you write sepal legnth or SepalLength. Column names in code are exact strings, and this is a classic source of the "my plot is empty" confusion.
  • Reading "sample length" literally. The spoken term was an accent-collision with "sepal length"; the actual dataset columns are the sepal measurements. When a demo's spoken names and the code's names differ, trust the code and the dataset.
  • Expecting a named file without output_file. No output_file means a random temp HTML — the chart appears, but you cannot find or reuse the file later.

Recap: The Iris example was the first real-dataset chart: import figure and show (no output_file), load flowers from bokeh.sampledata.iris, feed sepal_length and sepal_width columns into p.circle with size/color/alpha and a top-left legend — and Bokeh renders 150 points into a random temp HTML. Next, the final trio of demos — line plot, bar chart, and histogram (Section 15.15).

15.15 Worked Examples: Line Plot, Bar Chart, and Histogram

15.15.1 Line Plot with Sine and Cosine

A second line plot used numpy to generate the sample data with the mathematical functions sine and cosine:

where is the shared horizontal coordinate, is the sine of each x value, and is the cosine of each x value. A figure was created with a title, two sets of data were passed, line color and line width were set for each, labels were given, and show produced the output. The result: two sine-like waves on the same chart — the sine and cosine curves — drawn with the line glyph (p.line), with the color and width as the glyph's attributes. This is the same structure as the first sine wave demo, but with multiple lines and styling. (As before, the mathematics was not the point — numpy was just the easiest way to generate the curves.)

Worked example — sine and cosine on one figure. The demo's essentials:

import numpy as np
from bokeh.plotting import figure, show

x = np.linspace(0, 2 * np.pi, 100)
y1 = np.sin(x)
y2 = np.cos(x)

p = figure(title="Sine and Cosine")
p.line(x, y1, legend_label="sin(x)", line_color="navy", line_width=2)
p.line(x, y2, legend_label="cos(x)", line_color="firebrick", line_width=2)
show(p)

The math: sine and cosine both oscillate between and as x goes from to (one full circle). At , and ; at , both equal about . The sine curve starts at 0 and rises; the cosine curve starts at 1 and falls — the two lines cross in the middle of the wave, which is exactly what makes the demo readable. Two p.line calls on the same figure p layer the curves as two toppings on one pizza.

Sense-check: two formulas, two lines, two legend entries — each curve stays within and they cross at the expected quarter-circle point, so the math and the chart agree.

15.15.2 Bar Chart of Fruit Counts

The bar chart demo used categorical data: a list of fruits with a list of counts. The code passed the fruit names as x and the counts as the bar heights, created the figure, and called p.vbar to draw a vertical bar per fruit. The counts in the demo included 5 for one fruit and 10 for orange — the top parameter tells Bokeh where each bar should stop, so a count of 10 produced a bar twice as high as a count of 5. The width and the per-bar colors were the customization attributes.

Worked example — the fruit count chart. Categorical x-values and numeric heights:

fruits = ["apple", "orange", "banana"]
counts = [5, 10, 3]

p.vbar(x=fruits, top=counts, width=0.5, color=["green", "orange", "yellow"])

The x-axis no longer holds numbers — it holds category names (apple, orange, banana) spaced evenly apart. The top list carries the heights: apple's bar stops at 5, orange's at 10, banana's at 3. The orange bar is exactly twice the height of the apple bar (10 vs 5) — the height scale is linear, so proportions are readable at a glance. The color list matches one color per bar.

Sense-check: three fruit names produced three bars whose heights equal the counts — orange (10) twice as tall as apple (5), banana (3) the shortest.

15.15.3 Histogram with the quad Glyph

The final example was a histogram. The data was generated as 1,000 random values drawn from a normal distribution using numpy — enough points for a smooth bell shape. Then:

  1. The figure was created with a title.
  2. p.quad(...) was called — the quad glyph is the command you use for a histogram; it calculates the heights and widths of the bins, and you pass top, bottom, left, right for each bin.
  3. Fill color and line color were set, and show rendered the histogram from the random data.

Worked example — the histogram, 1,000 random values. The demo's structure:

import numpy as np
from bokeh.plotting import figure, show

values = np.random.normal(size=1000)

p = figure(title="Histogram of 1000 Normal Values")
p.quad(top=bins_top, bottom=bins_bottom, left=bins_left, right=bins_right,
       fill_color="navy", line_color="white")
show(p)

A histogram is a "how many are in this range?" chart. numpy draws 1,000 values that cluster around 0 (the center of a normal distribution), and the histogram divides the number line into adjacent bins — say, to , to , and so on — then counts how many of the 1,000 values fall into each. Each bin is a rectangle, which is why the quad glyph (four edges: top, bottom, left, right) is the natural engine: left and right mark the bin's range on the x-axis, bottom sits at 0, and top is the bin's count. The bins sit side by side with no gaps, so the rectangles merge into the familiar bell shape.

Sense-check: most of the 1,000 values land near the middle, so the tallest bars sit at the center and the bars taper symmetrically on both sides — a bell, as a normal distribution should produce.

The lesson: by saying one word — quad — Bokeh knows you want a histogram and builds the bins from the variables you pass. These are the very fundamental features of Bokeh: line, markers, bars, histograms, all driven by glyph calls with a figure underneath.

Relax the math, keep the shapes. The sine, cosine, and normal-distribution mathematics behind these demos was expressly out of scope — numpy was only generating demo data so the class could see the glyphs at work. What matters is the chart-side knowledge: sine and cosine draw two wavy lines, and a normal distribution draws a bell-shaped histogram. If the wave curves or the bell shape appear as expected, the demo succeeded.

Exam note: repeated reassurance was given that the class should not feel pressurized by the volume of code shown — the aim was to cover maximum capability so students have an idea of what is possible, not to demand every syntax be memorized. "Don't get pressurized by seeing so much of the code." What should stick: p.line for curves, p.vbar for category counts, p.quad for histogram bins.

15.16 Recap and What Comes Next

15.16.1 What We Learned Today

The closing recap summarized the session into four takeaways:

  1. Glyphs — the fundamental building blocks of Bokeh. You saw how to call line, bar, and the histogram glyph, and how each represents a different visual element — markers, lines, bars, shapes — letting you represent data meaningfully.
  2. The different plot types — scatter plot (using the circle glyph), line plot (using the line glyph), bar chart (using the vbar glyph), and histogram (using the quad glyph). The glyph you choose is how you create each graph.
  3. Customizing glyphs — by passing parameters: labels, x-axis values, width, color, size, alpha. That is how every glyph is customized.
  4. The documentation and community — how rich the website is, how much documentation exists, and how strong the user community is.

The session in one mental model. Every chart from today is the same recipe with one variable ingredient: the figure is the pizza base, the data is the flavor, and the glyph is the topping — circle for scatter, line for trends, vbar/hbar for bars, quad for histograms. Attributes (size, color, line width, alpha) are the seasoning. If you can name the glyph for the chart you want, you already know the next step in the workflow from Section 15.6.

15.16.2 What Comes Next: Data Sources and a Full-Course Recap

Tomorrow's session has a clear agenda:

  • Plotting Bokeh with different data sources — the ColumnDataSource (Section 15.9.5) and how glyphs connect to real data.
  • More Bokeh — possibly some server-side application work.
  • A quick recap of the entire course — a fast, high-level brush-up of all the key things learned from the first session up to Bokeh.

Tomorrow is the last class, and it will wrap up the course. Students were invited to make a list of queries to discuss then. The closing advice: "Keep learning — that is my suggestion to you."

Exam note: tomorrow is the last class — a full-course recap, so bring your list of queries. This Bokeh session itself closes with the four takeaways: glyphs as building blocks, the plot-type-to-glyph mapping (scatter = circle, line = line, bar = vbar, histogram = quad), glyph customization via parameters, and the strength of the documentation and community.

15.16.3 Student Questions and Answers

Q: Any question or query before we wrap up? A: Students had none — one student said the class was good and would catch up tomorrow, and another confirmed everything was fine. The session closed with the plan for the final class.

Exam Guidance Summary

  • Code details are not the exam target. It was said explicitly: "I will not give these kind of codes and all that in exam, so don't worry about this." The exact glyph function calls, parameter lists, and marker names shown in the demos are capabilities to know about, not lines to memorize for the exam.
  • Know the core syntax. Even though code details will not be asked, you should know the syntax of the core workflow — the figure, output_file, and show pattern — and what each command does.
  • Interface layers are context, not exam material. The model/plotting/chart stack and the bokeh.js JSON mechanism were described as "for those who are techie in nature" — there is no need to memorize them, but knowing they exist is good context.
  • Know when to use which library. The Matplotlib vs Seaborn vs Bokeh comparison was repeated for emphasis, and it was called out as always worth reminding ourselves of: static publication plots → Matplotlib; statistical graphs → Seaborn; interactive web-based dashboards → Bokeh. Expect conceptual, comparison-style understanding to matter more than code recall.
  • Do not feel pressurized by the volume of code. The demos were chosen to cover maximum capability in limited time. The explicit reassurance: you do not have to memorize this — the idea is to know what Bokeh can do. Once you practice a few examples yourself, the steps become automatic.
  • Understand what each glyph does. Scatter = circle glyph, line = line glyph, bar = vbar/hbar, histogram = quad. Knowing which glyph creates which chart is the conceptual core of the session.
  • Next class is the last one. Tomorrow brings a full-course recap — bring your list of queries, because it is the final chance to ask.

Key Industry Applications

  • Interactive web dashboards. Bokeh is the go-to when a dashboard must live in the browser: pan, zoom, tooltips, and filtering come free with every chart. Dynamic dashboards and applications are Bokeh's stated focus — the operational, analytical, and strategic dashboard roles all benefit from the free interactivity.
  • Web application integration. Bokeh generates HTML and JavaScript-based visualization, so charts can be deployed on web pages and integrated with web frameworks like Flask — Python integration is shared with the other libraries, but web integration is Bokeh's edge. A Flask site can embed a live Bokeh chart the same way it embeds any page element.
  • Data work with Pandas and NumPy. Bokeh integrates with the standard data manipulation stack: numpy arrays and pandas data frames feed the glyphs directly, and the ColumnDataSource (next session) binds database tables to x and y coordinates. The sine/cosine and histogram demos were numpy-fed; the Iris scatter was data-frame-fed.
  • The Iris dataset (bokeh.sampledata.iris) — a built-in sample dataset used across the Python ecosystem for demonstrations and tutorials; the sepal length vs sepal width scatter is a canonical example. Libraries ship sample data precisely so every learner can reproduce the official examples.
  • The Bokeh gallery and user guide — an industry-standard resource: browse the gallery, copy the sample code behind any chart, and adapt it. The site also shows installation and first steps. Adapting official samples is how working engineers build most of their charts.
  • Tableau comparison. Everything the class learned in Tableau carries over conceptually — data source, sheets, dashboards — with drag-and-drop replaced by code. Bokeh charts are free and unlimited in variety compared to the fixed set of chart types in commercial drag-and-drop tools.
  • Learning environments. Jupyter and Google Colab ship with the basic libraries preinstalled, which is how most practitioners start with Bokeh without any installation step. The pip install bokeh command is only needed in plain prompt-based environments.

DVI Lecture 15 notes · Bokeh: Interactive Visualization in Python

Data Visualization and Interpretation· postgraduate· 2026-08-11

Sections Breakdown

115.1 What Is Bokeh

The core definition of Bokeh as a Python library for interactive, web-browser-based visualizations, the free default toolbar (pan, reset, box zoom, wheel zoom, save), student Q&A, common pitfalls, and the dashboard use case.

215.2 Why Use Bokeh

The five reasons to choose Bokeh: interactive and engaging visualization, cleaner and sharper output, web integration, one library for both simple and complex charts, and open source with an active community.

315.3 The Bokeh Website and Documentation

A tour of the Bokeh home page, the user guide, and the interactive gallery in which every chart carries its sample code, supporting the standard adapt-the-example professional workflow.

415.4 Prerequisites

The software and knowledge prerequisites: a working Python installation with pip, basic Python syntax, debugging and data structures, with HTML and CSS optional.

515.5 Installation and Version Check

The pip install command, the import-and-print version check, the worked version check from the live demo, and how to read a three-part version number.

615.6 The Core Bokeh Workflow

The core workflow: the figure, output_file, and show trio, the six-step pipeline every visualization follows, and how it maps onto the Tableau workflow the class already knows.

715.7 Bokeh vs Matplotlib vs Seaborn

The parameter-by-parameter comparison of Matplotlib, Seaborn, and Bokeh: purpose and focus, ease of use, interactivity and deployment, use cases, and ecosystem, with the key intuition of choosing by purpose rather than chart type.

815.8 Bokeh Interface Layers

Bokeh's bottom-up interface layers (model, plotting, chart) and how the Python library produces JSON descriptions that bokeh.js renders in the browser.

915.9 Glyphs — The Building Blocks

Glyphs as the building blocks of Bokeh: markers, lines, and bars and rectangles, the professor's pizza analogy, the attributes (size, color, line width, alpha), and a preview of the ColumnDataSource.

1015.10 Worked Example: The First Line Graph (Sine Wave)

The first worked example: the six-line sine wave demo with real numbers, the interactive toolbar it gets for free, and what deprecation warnings tell you as the API evolves.

1115.11 Worked Examples: Scatter Markers

Worked examples on scatter markers: the one-word difference between p.circle, p.square, and p.plus, and the large predefined marker catalog.

1215.12 Worked Examples: The Line Glyph Family

The line glyph family: p.line, p.step, p.multi_line, the honest gap drawn for null values, and the stacked vline_stack and hline_stack variants.

1315.13 Worked Examples: Bar and Rectangle Glyphs

Bar and rectangle glyphs: p.vbar and p.hbar, horizontal stacked bars, and the four-edge quad rectangle that also powers histograms.

1415.14 Worked Example: Scatter Plot with the Iris Dataset

The first real-dataset worked example: the Iris scatter with sepal length against sepal width, size/color/alpha customization, and what happens when output_file is skipped.

1515.15 Worked Examples: Line Plot, Bar Chart, and Histogram

The final trio of worked examples: sine and cosine on one figure, the fruit-count bar chart, and the 1,000-value histogram built with the quad glyph.

1615.16 Recap and What Comes Next

The session recap: glyphs as building blocks, the plot-type-to-glyph mapping, customization through parameters, the documentation and community, and what comes next in the final class.

17Exam Guidance Summary

The professor's exam strategy: code details are not the exam target, know the core figure/output_file/show syntax, master the when-to-use-which-library comparison, and know which glyph builds which chart.

18Key Industry Applications

Where Bokeh lives in industry: interactive web dashboards, Flask web integration, Pandas and NumPy data work, the Iris dataset, the gallery workflow, the Tableau comparison, and notebook learning environments.

Postgraduate students in data visualization and business intelligence

Exam Revision Notes

Below is the distilled, exam-ready core. Every entry comes from the full explanation above. Use this section for rapid review; return to the main notes when a point needs more context.

What Is Bokeh

Must-know: Bokeh generates interactive visualizations in the web browser; the whole point is interactivity (pan, zoom, hover, tooltips, filtering) plus easy integration with web applications.

⚠️ Top pitfall: Treating a Bokeh plot as a static image instead of opening the interactive HTML page in a browser.

Self-check: Which five tools arrive for free in every Bokeh chart's default toolbar?

Connects to: Why Use Bokeh (15.2), The Core Bokeh Workflow (15.6), Glyphs — The Building Blocks (15.9), Recap and What Comes Next (15.16)

Why Use Bokeh

Must-know: Bokeh's edge over the other libraries is web integration and interactivity; its output is HTML/JavaScript that can be embedded in pages; it handles both simple basic graphs and complex dashboards.

⚠️ Top pitfall: Assuming Bokeh is only for big dashboards — the same library draws plain line graphs and scatter plots with five lines of code.

Self-check: List the five reasons the lecture gives for choosing Bokeh.

Connects to: What Is Bokeh (15.1), The Bokeh Website and Documentation (15.3), Bokeh vs Matplotlib vs Seaborn (15.7)

The Bokeh Website and Documentation

Must-know: The Bokeh gallery is interactive and exposes the sample code behind every chart; the standard professional workflow is to find the closest example and adapt it.

⚠️ Top pitfall: Using the gallery as a menu (what exists) without following the link to the sample code (how it is built).

Self-check: Where on the Bokeh site would you find the exact code behind a chart you like?

Connects to: Installation and Version Check (15.5), Worked Example: The First Line Graph (Sine Wave) (15.10)

Prerequisites

Must-know: You need Python + pip and basic Python knowledge (syntax, debugging, data structures) — not data-science expertise; HTML/CSS is optional and only helps with embedding.

⚠️ Top pitfall: Reading an error message at the wrong level: 'ModuleNotFoundError' usually means the package was never installed, and case-sensitive names like figure vs Figure cause many beginner bugs.

Self-check: Why do Jupyter and Google Colab users often skip the pip install step?

Connects to: Installation and Version Check (15.5), The Core Bokeh Workflow (15.6)

Installation and Version Check

Must-know: The install/version-check pattern: pip install bokeh, then import bokeh and print bokeh.__version__; a version mismatch with the website is normal.

⚠️ Top pitfall: Panicking when the installed version differs from the version shown on the website — many versions exist and any of them works.

Self-check: What do the two lines `import bokeh` and `print(bokeh.__version__)` together prove?

Connects to: Prerequisites (15.4), The Core Bokeh Workflow (15.6)

The Core Bokeh Workflow

Must-know: The three always-used imports: figure (canvas/template for the plot), output_file (names the HTML file, optional), show (displays the chart); the six-step pipeline maps to Tableau's data-source → sheets → dashboards flow.

⚠️ Top pitfall: Skipping output_file and later getting a random-named HTML file in the temp folder — name the file if you want a meaningful one.

Self-check: What are the six steps every Bokeh visualization follows?

Connects to: What Is Bokeh (15.1), Installation and Version Check (15.5), Glyphs — The Building Blocks (15.9), Worked Example: The First Line Graph (Sine Wave) (15.10)

Bokeh vs Matplotlib vs Seaborn

Must-know: The when-to-use-which-library criterion: static publication plots → Matplotlib, statistical graphs → Seaborn, interactive web dashboards → Bokeh (HTML/JavaScript output). Not one library per chart — all three make most common plots.

⚠️ Top pitfall: The 'one chart, one library' myth — the chart types overlap; choose by purpose, not by chart type.

Self-check: Which of the three libraries produces HTML/JavaScript output that deploys on a web page?

Connects to: What Is Bokeh (15.1), Why Use Bokeh (15.2), Bokeh Interface Layers (15.8), Recap and What Comes Next (15.16)

Bokeh Interface Layers

Must-know: Interface layers in bottom-up order: model → plotting → chart; the Python library produces JSON that bokeh.js renders in the browser. Layers are context only — know the plotting-level syntax.

⚠️ Top pitfall: Trying to memorize the technical stack — the professor said it is for the curious; the exam-relevant part is the plotting-level syntax.

Self-check: Which of the two halves of Bokeh runs inside the browser, and what does it render?

Connects to: The Core Bokeh Workflow (15.6), Bokeh vs Matplotlib vs Seaborn (15.7), Glyphs — The Building Blocks (15.9)

Glyphs — The Building Blocks

Must-know: Glyphs are the building blocks: markers (circles, squares, triangles), lines (line, step, multi_line, vline_stack), bars and rectangles (vbar, hbar, quad); attributes size/color/line width/alpha customize them; data controls glyph sizes.

⚠️ Top pitfall: Confusing the glyph with the figure, or passing a marker attribute (like size) to a bar glyph that expects top/right and width.

Self-check: In the pizza analogy, what do the toppings represent and what does the flavor represent?

Connects to: The Core Bokeh Workflow (15.6), Worked Example: The First Line Graph (Sine Wave) (15.10), Worked Examples: Scatter Markers (15.11), Worked Examples: Bar and Rectangle Glyphs (15.13)

Worked Example: The First Line Graph (Sine Wave)

Must-know: The six-line pattern: imports (figure, output_file, show + numpy), data y = sin(x) with random x using pi, output_file('sine_wave.html'), figure with title and axis labels, p.line(x, y, legend_label=...), show(p). Code details are NOT exam material.

⚠️ Top pitfall: Panicking at deprecation warnings — they are library help (label became legend_label/legend_field); update the name and move on. Code details are not on the exam.

Self-check: What does the deprecation warning about 'label' tell you to use instead?

Connects to: The Core Bokeh Workflow (15.6), Glyphs — The Building Blocks (15.9), Worked Examples: Scatter Markers (15.11), Worked Examples: Line Plot, Bar Chart, and Histogram (15.15)

Worked Examples: Scatter Markers

Must-know: One word changes the whole chart: p.circle / p.square / p.plus with identical data and attributes; Bokeh ships many predefined markers (p.circle_cross, p.circle_dot, p.diamond, ...) — everything is predefined, you just call it.

⚠️ Top pitfall: Trying to memorize the full marker catalog — pick markers for readability (shape distinguishes series when color cannot), the website lists them all.

Self-check: What is the only difference between the circle, square, and plus demos?

Connects to: Glyphs — The Building Blocks (15.9), Worked Example: The First Line Graph (Sine Wave) (15.10), Worked Examples: The Line Glyph Family (15.12)

Worked Examples: The Line Glyph Family

Must-know: Line glyph family: p.line (continuous), p.step (flat + jump), p.multi_line (several lines one call), null in the data = visible gap in the line, p.vline_stack / p.hline_stack stack series (Y1, Y2 over X).

⚠️ Top pitfall: Deleting a value instead of marking it null shifts all later points — mark holes with null so the chart shows the gap honestly.

Self-check: What happens to a p.line chart when one y value in the middle of the list is null?

Connects to: Glyphs — The Building Blocks (15.9), Worked Example: The First Line Graph (Sine Wave) (15.10), Worked Examples: Scatter Markers (15.11), Worked Examples: Bar and Rectangle Glyphs (15.13)

Worked Examples: Bar and Rectangle Glyphs

Must-know: vbar uses top (height) + width + color; hbar uses right (length) + height; stacked bars layer variables end to end (X1, X2); quad draws rectangles from top/bottom/left/right edges and builds histograms.

⚠️ Top pitfall: Confusing the parameter directions: vertical bars take top, horizontal bars take right, quad needs all four edges — one alphabet (vbar→hbar) flips the whole chart type.

Self-check: Which parameter tells p.hbar where a bar ends, and what does it mean?

Connects to: Glyphs — The Building Blocks (15.9), Worked Examples: The Line Glyph Family (15.12), Worked Examples: Line Plot, Bar Chart, and Histogram (15.15)

Worked Example: Scatter Plot with the Iris Dataset

Must-know: Real-data pattern: import figure and show (output_file optional), load a sample dataset (bokeh.sampledata.iris → flowers), feed data-frame columns into a glyph (p.circle with sepal_length x, sepal_width y), customize with size/color/alpha, position the legend top-left.

⚠️ Top pitfall: Typing column names wrong (exact strings like flowers['sepal_length']) or expecting a named file when output_file was skipped — Bokeh creates a random temp HTML instead.

Self-check: Why did the Iris demo use alpha=0.5 even though the points are plain circles?

Connects to: The Core Bokeh Workflow (15.6), Glyphs — The Building Blocks (15.9), Worked Examples: Scatter Markers (15.11)

Worked Examples: Line Plot, Bar Chart, and Histogram

Must-know: p.line draws curves (two calls stack sine and cosine on one figure); p.vbar draws category bars where top equals the count (10 is twice 5); p.quad builds histograms from bins given as top/bottom/left/right edges. Don't feel pressurized by the volume of code — capabilities, not memorization.

⚠️ Top pitfall: Feeling pressurized by the demo volume — the mathematics (sine/cosine/normal) was only numpy demo data; the exam-relevant part is knowing which glyph builds which chart.

Self-check: Which glyph builds a histogram, and what four edge parameters does it take per bin?

Connects to: Worked Example: The First Line Graph (Sine Wave) (15.10), Worked Examples: The Line Glyph Family (15.12), Worked Examples: Bar and Rectangle Glyphs (15.13)

Recap and What Comes Next

Must-know: Which glyph makes which chart: scatter = circle, line plot = line, bar chart = vbar/hbar, histogram = quad; customization happens through parameters; tomorrow is the last class with a full-course recap.

⚠️ Top pitfall: Leaving tomorrow's class without your list of queries — it is the last chance to ask the professor about the whole course.

Self-check: Which glyph would you use for a histogram, and why does it fit?

Connects to: Glyphs — The Building Blocks (15.9), Worked Example: The First Line Graph (Sine Wave) (15.10), Worked Examples: Scatter Markers (15.11), Worked Examples: Bar and Rectangle Glyphs (15.13), Worked Examples: Line Plot, Bar Chart, and Histogram (15.15)

Exam Guidance Summary

Must-know: Scatter = circle glyph, line = line glyph, bar = vbar/hbar, histogram = quad; the library comparison (purpose and focus decides); core syntax known; code details not examinable.

⚠️ Top pitfall: Memorizing glyph parameter lists that the professor explicitly said will not be asked.

Self-check: What does the professor say about the exact code details shown in the demos?

Connects to: Bokeh vs Matplotlib vs Seaborn (15.7), Worked Example: The First Line Graph (Sine Wave) (15.10), Recap and What Comes Next (15.16)

Key Industry Applications

Must-know: Bokeh's industry edge is interactive web deployment (HTML/JavaScript, Flask integration), with Pandas/NumPy feeding glyphs and ColumnDataSource binding tables to coordinates.

⚠️ Top pitfall: Underestimating the gallery workflow — browsing the gallery and adapting sample code is the standard professional practice.

Self-check: Name two ways Bokeh integrates with the broader Python web ecosystem.

Connects to: Why Use Bokeh (15.2), The Bokeh Website and Documentation (15.3), Worked Example: Scatter Plot with the Iris Dataset (15.14)

Was this lecture useful?

Loading comments…
🤖

BitsNotes AI Assistant

Subject Notes Assistant

Configure AI Chat

Choose how to access the chatbot
Have your own API key?

Switch to "Bring Your Own Key" tab above for unlimited access with any OpenAI-compatible provider.

🔑 Enter API key above to fetch live models from provider, or enter model name manually.
OpenAI-Compatible API Support

Choose any provider preset (Gemini, DeepSeek, Kimi, GLM, MiniMax, Qwen, OpenAI, Groq, Ollama, etc.) or enter a custom endpoint URL.

Security & Privacy First

Your API key is sent directly from your browser to your specified provider. BitsNotes servers never store or see your key.