We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
app_reveal fails importing old plotting stuff
```
(py34devel)[damian@damian-S400CA][slideshow](master)$ python app_reveal.py 
Traceback (most recent call last):
  File "app_reveal.py", line 19, in <module>
    from bokeh.plotting import (annular_wedge, cursession, figure, hold, legend,
ImportError: cannot import name 'annular_wedge'
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `examples/embed/slideshow/app_reveal.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 """
3 In this example, we want to show you how you can take isolated blocks of code
4 (featuring different kinds of Bokeh visualizations) and rearrange them in a
5 bigger (encompassing) flask-based application without losing the independence
6 of each example. This is the reason of some weirdness through the code.
7 We are using this "building blocks" approach here because we believe it has some
8 conceptual advantages for people trying to quickly understand, and more
9 importantly, use the embed API, in a more complex way than just a simple script.
10 """
11 import time
12 from threading import Thread
13 
14 import numpy as np
15 import scipy.special
16 
17 from bokeh.embed import autoload_server
18 from bokeh.models import GlyphRenderer
19 from bokeh.plotting import (annular_wedge, cursession, figure, hold, legend,
20                             line, output_server, push, quad, xgrid, ygrid)
21 
22 from flask import Flask, render_template
23 app = Flask(__name__)
24 
25 @app.route('/')
26 def render_plot():
27     """
28     Get the script tags from each plot object and "insert" them into the template.
29 
30     This also starts different threads for each update function, so you can have
31     a non-blocking update.
32     """
33     dist_plot, dist_session = distribution()
34     dist_tag = autoload_server(dist_plot, dist_session)
35 
36     anim_plot, anim_session = animated()
37     anim_tag = autoload_server(anim_plot, anim_session)
38     # for update_animation as target we need to pass the anim_plot and anim_session as args
39     thread = Thread(target=update_animation, args=(anim_plot, anim_session))
40     thread.start()
41 
42     pop = Population()
43     pop_tag = autoload_server(pop.layout, pop.session)
44     # for update_population as target we need to pass the pop instance as args
45     thread = Thread(target=update_population, args=(pop,))
46     thread.start()
47 
48     return render_template('app_plot.html', tag1=dist_tag, tag2=anim_tag, tag3=pop_tag)
49 
50 
51 def distribution():
52 
53     mu, sigma = 0, 0.5
54 
55     measured = np.random.normal(mu, sigma, 1000)
56     hist, edges = np.histogram(measured, density=True, bins=20)
57 
58     x = np.linspace(-2, 2, 1000)
59     pdf = 1 / (sigma * np.sqrt(2 * np.pi)) * np.exp(-(x - mu) ** 2 / (2 * sigma ** 2))
60     cdf = (1 + scipy.special.erf((x - mu) / np.sqrt(2 * sigma ** 2))) / 2
61 
62     output_server("distribution_reveal")
63 
64     p = figure(title="Interactive plots",
65                background_fill="#E5E5E5")
66     p.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],
67            fill_color="#333333", line_color="#E5E5E5", line_width=3)
68 
69     # Use `line` renderers to display the PDF and CDF
70     p.line(x, pdf, line_color="#348abd", line_width=8, alpha=0.7, legend="PDF")
71     p.line(x, cdf, line_color="#7a68a6", line_width=8, alpha=0.7, legend="CDF")
72 
73     p.legend.orientation = "top_left"
74 
75     p.xaxis.axis_label = 'x'
76     p.xgrid[0].grid_line_color = "white"
77     p.xgrid[0].grid_line_width = 3
78 
79     p.yaxis.axis_label = 'Pr(x)'
80     p.ygrid[0].grid_line_color = "white"
81     p.ygrid[0].grid_line_width = 3
82 
83     push()
84 
85     return p, cursession()
86 
87 
88 def animated():
89 
90     from numpy import pi, cos, sin, linspace
91 
92     N = 50 + 1
93     r_base = 8
94     theta = linspace(0, 2 * pi, N)
95     r_x = linspace(0, 6 * pi, N - 1)
96     rmin = r_base - cos(r_x) - 1
97     rmax = r_base + sin(r_x) + 1
98 
99     colors = ["FFFFCC", "#C7E9B4", "#7FCDBB", "#41B6C4", "#2C7FB8",
100               "#253494", "#2C7FB8", "#41B6C4", "#7FCDBB", "#C7E9B4"] * 5
101 
102     output_server("animated_reveal")
103 
104     p = figure(title="Animations", x_range=[-11, 11], y_range=[-11, 11])
105 
106     p.annular_wedge(
107         0, 0, rmin, rmax, theta[:-1], theta[1:],
108         inner_radius_units="data",
109         outer_radius_units="data",
110         fill_color=colors,
111         line_color="black",
112     )
113 
114     push()
115 
116     return p, cursession()
117 
118 
119 def update_animation(plot, session):
120 
121     from numpy import roll
122 
123     renderer = plot.select(dict(type=GlyphRenderer))
124     ds = renderer[0].data_source
125 
126     while True:
127 
128         rmin = ds.data["inner_radius"]
129         rmin = roll(rmin, 1)
130         ds.data["inner_radius"] = rmin
131 
132         rmax = ds.data["outer_radius"]
133         rmax = roll(rmax, -1)
134         ds.data["outer_radius"] = rmax
135 
136         cursession().store_objects(ds)
137         time.sleep(0.1)
138 
139 
140 class Population(object):
141 
142     year = 2010
143     location = "World"
144 
145     def __init__(self):
146         from bokeh.models import ColumnDataSource
147         from bokeh.document import Document
148         from bokeh.session import Session
149         from bokeh.sampledata.population import load_population
150 
151         self.document = Document()
152         self.session = Session()
153         self.session.use_doc('population_reveal')
154         self.session.load_document(self.document)
155 
156         self.df = load_population()
157         self.source_pyramid = ColumnDataSource(data=dict())
158 
159         # just render at the initialization
160         self._render()
161 
162     def _render(self):
163         self.pyramid_plot()
164         self.create_layout()
165         self.document.add(self.layout)
166         self.update_pyramid()
167 
168     def pyramid_plot(self):
169         from bokeh.models import (Plot, DataRange1d, LinearAxis, Grid,
170                                   Legend, SingleIntervalTicker)
171         from bokeh.models.glyphs import Quad
172 
173         xdr = DataRange1d(sources=[self.source_pyramid.columns("male"),
174                                    self.source_pyramid.columns("female")])
175         ydr = DataRange1d(sources=[self.source_pyramid.columns("groups")])
176 
177         self.plot = Plot(title="Widgets", x_range=xdr, y_range=ydr,
178                          plot_width=600, plot_height=600)
179 
180         xaxis = LinearAxis()
181         self.plot.add_layout(xaxis, 'below')
182         yaxis = LinearAxis(ticker=SingleIntervalTicker(interval=5))
183         self.plot.add_layout(yaxis, 'left')
184 
185         self.plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
186         self.plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))
187 
188         male_quad = Quad(left="male", right=0, bottom="groups", top="shifted",
189                          fill_color="#3B8686")
190         male_quad_glyph = self.plot.add_glyph(self.source_pyramid, male_quad)
191 
192         female_quad = Quad(left=0, right="female", bottom="groups", top="shifted",
193                            fill_color="#CFF09E")
194         female_quad_glyph = self.plot.add_glyph(self.source_pyramid, female_quad)
195 
196         self.plot.add_layout(Legend(legends=dict(Male=[male_quad_glyph],
197                                                  Female=[female_quad_glyph])))
198 
199     def on_year_change(self, obj, attr, old, new):
200         self.year = int(new)
201         self.update_pyramid()
202 
203     def on_location_change(self, obj, attr, old, new):
204         self.location = new
205         self.update_pyramid()
206 
207     def create_layout(self):
208         from bokeh.models.widgets import Select, HBox, VBox
209 
210         years = list(map(str, sorted(self.df.Year.unique())))
211         locations = sorted(self.df.Location.unique())
212 
213         year_select = Select(title="Year:", value="2010", options=years)
214         location_select = Select(title="Location:", value="World", options=locations)
215 
216         year_select.on_change('value', self.on_year_change)
217         location_select.on_change('value', self.on_location_change)
218 
219         controls = HBox(year_select, location_select)
220         self.layout = VBox(controls, self.plot)
221 
222     def update_pyramid(self):
223         pyramid = self.df[(self.df.Location == self.location) & (self.df.Year == self.year)]
224 
225         male = pyramid[pyramid.Sex == "Male"]
226         female = pyramid[pyramid.Sex == "Female"]
227 
228         total = male.Value.sum() + female.Value.sum()
229 
230         male_percent = -male.Value / total
231         female_percent = female.Value / total
232 
233         groups = male.AgeGrpStart.tolist()
234         shifted = groups[1:] + [groups[-1] + 5]
235 
236         self.source_pyramid.data = dict(
237             groups=groups,
238             shifted=shifted,
239             male=male_percent,
240             female=female_percent,
241         )
242         self.session.store_document(self.document)
243 
244 
245 def update_population(plot):
246     while True:
247         plot.session.load_document(plot.document)
248         time.sleep(0.1)
249 
250 if __name__ == '__main__':
251     app.run(debug=True)
252
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/examples/embed/slideshow/app_reveal.py b/examples/embed/slideshow/app_reveal.py
--- a/examples/embed/slideshow/app_reveal.py
+++ b/examples/embed/slideshow/app_reveal.py
@@ -16,8 +16,7 @@
 
 from bokeh.embed import autoload_server
 from bokeh.models import GlyphRenderer
-from bokeh.plotting import (annular_wedge, cursession, figure, hold, legend,
-                            line, output_server, push, quad, xgrid, ygrid)
+from bokeh.plotting import cursession, figure, output_server, push
 
 from flask import Flask, render_template
 app = Flask(__name__)

{"golden_diff": "diff --git a/examples/embed/slideshow/app_reveal.py b/examples/embed/slideshow/app_reveal.py\n--- a/examples/embed/slideshow/app_reveal.py\n+++ b/examples/embed/slideshow/app_reveal.py\n@@ -16,8 +16,7 @@\n \n from bokeh.embed import autoload_server\n from bokeh.models import GlyphRenderer\n-from bokeh.plotting import (annular_wedge, cursession, figure, hold, legend,\n-                            line, output_server, push, quad, xgrid, ygrid)\n+from bokeh.plotting import cursession, figure, output_server, push\n \n from flask import Flask, render_template\n app = Flask(__name__)\n", "issue": "app_reveal fails importing old plotting stuff\n```\n(py34devel)[damian@damian-S400CA][slideshow](master)$ python app_reveal.py \nTraceback (most recent call last):\n  File \"app_reveal.py\", line 19, in <module>\n    from bokeh.plotting import (annular_wedge, cursession, figure, hold, legend,\nImportError: cannot import name 'annular_wedge'\n```\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"\nIn this example, we want to show you how you can take isolated blocks of code\n(featuring different kinds of Bokeh visualizations) and rearrange them in a\nbigger (encompassing) flask-based application without losing the independence\nof each example. This is the reason of some weirdness through the code.\nWe are using this \"building blocks\" approach here because we believe it has some\nconceptual advantages for people trying to quickly understand, and more\nimportantly, use the embed API, in a more complex way than just a simple script.\n\"\"\"\nimport time\nfrom threading import Thread\n\nimport numpy as np\nimport scipy.special\n\nfrom bokeh.embed import autoload_server\nfrom bokeh.models import GlyphRenderer\nfrom bokeh.plotting import (annular_wedge, cursession, figure, hold, legend,\n                            line, output_server, push, quad, xgrid, ygrid)\n\nfrom flask import Flask, render_template\napp = Flask(__name__)\n\n@app.route('/')\ndef render_plot():\n    \"\"\"\n    Get the script tags from each plot object and \"insert\" them into the template.\n\n    This also starts different threads for each update function, so you can have\n    a non-blocking update.\n    \"\"\"\n    dist_plot, dist_session = distribution()\n    dist_tag = autoload_server(dist_plot, dist_session)\n\n    anim_plot, anim_session = animated()\n    anim_tag = autoload_server(anim_plot, anim_session)\n    # for update_animation as target we need to pass the anim_plot and anim_session as args\n    thread = Thread(target=update_animation, args=(anim_plot, anim_session))\n    thread.start()\n\n    pop = Population()\n    pop_tag = autoload_server(pop.layout, pop.session)\n    # for update_population as target we need to pass the pop instance as args\n    thread = Thread(target=update_population, args=(pop,))\n    thread.start()\n\n    return render_template('app_plot.html', tag1=dist_tag, tag2=anim_tag, tag3=pop_tag)\n\n\ndef distribution():\n\n    mu, sigma = 0, 0.5\n\n    measured = np.random.normal(mu, sigma, 1000)\n    hist, edges = np.histogram(measured, density=True, bins=20)\n\n    x = np.linspace(-2, 2, 1000)\n    pdf = 1 / (sigma * np.sqrt(2 * np.pi)) * np.exp(-(x - mu) ** 2 / (2 * sigma ** 2))\n    cdf = (1 + scipy.special.erf((x - mu) / np.sqrt(2 * sigma ** 2))) / 2\n\n    output_server(\"distribution_reveal\")\n\n    p = figure(title=\"Interactive plots\",\n               background_fill=\"#E5E5E5\")\n    p.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],\n           fill_color=\"#333333\", line_color=\"#E5E5E5\", line_width=3)\n\n    # Use `line` renderers to display the PDF and CDF\n    p.line(x, pdf, line_color=\"#348abd\", line_width=8, alpha=0.7, legend=\"PDF\")\n    p.line(x, cdf, line_color=\"#7a68a6\", line_width=8, alpha=0.7, legend=\"CDF\")\n\n    p.legend.orientation = \"top_left\"\n\n    p.xaxis.axis_label = 'x'\n    p.xgrid[0].grid_line_color = \"white\"\n    p.xgrid[0].grid_line_width = 3\n\n    p.yaxis.axis_label = 'Pr(x)'\n    p.ygrid[0].grid_line_color = \"white\"\n    p.ygrid[0].grid_line_width = 3\n\n    push()\n\n    return p, cursession()\n\n\ndef animated():\n\n    from numpy import pi, cos, sin, linspace\n\n    N = 50 + 1\n    r_base = 8\n    theta = linspace(0, 2 * pi, N)\n    r_x = linspace(0, 6 * pi, N - 1)\n    rmin = r_base - cos(r_x) - 1\n    rmax = r_base + sin(r_x) + 1\n\n    colors = [\"FFFFCC\", \"#C7E9B4\", \"#7FCDBB\", \"#41B6C4\", \"#2C7FB8\",\n              \"#253494\", \"#2C7FB8\", \"#41B6C4\", \"#7FCDBB\", \"#C7E9B4\"] * 5\n\n    output_server(\"animated_reveal\")\n\n    p = figure(title=\"Animations\", x_range=[-11, 11], y_range=[-11, 11])\n\n    p.annular_wedge(\n        0, 0, rmin, rmax, theta[:-1], theta[1:],\n        inner_radius_units=\"data\",\n        outer_radius_units=\"data\",\n        fill_color=colors,\n        line_color=\"black\",\n    )\n\n    push()\n\n    return p, cursession()\n\n\ndef update_animation(plot, session):\n\n    from numpy import roll\n\n    renderer = plot.select(dict(type=GlyphRenderer))\n    ds = renderer[0].data_source\n\n    while True:\n\n        rmin = ds.data[\"inner_radius\"]\n        rmin = roll(rmin, 1)\n        ds.data[\"inner_radius\"] = rmin\n\n        rmax = ds.data[\"outer_radius\"]\n        rmax = roll(rmax, -1)\n        ds.data[\"outer_radius\"] = rmax\n\n        cursession().store_objects(ds)\n        time.sleep(0.1)\n\n\nclass Population(object):\n\n    year = 2010\n    location = \"World\"\n\n    def __init__(self):\n        from bokeh.models import ColumnDataSource\n        from bokeh.document import Document\n        from bokeh.session import Session\n        from bokeh.sampledata.population import load_population\n\n        self.document = Document()\n        self.session = Session()\n        self.session.use_doc('population_reveal')\n        self.session.load_document(self.document)\n\n        self.df = load_population()\n        self.source_pyramid = ColumnDataSource(data=dict())\n\n        # just render at the initialization\n        self._render()\n\n    def _render(self):\n        self.pyramid_plot()\n        self.create_layout()\n        self.document.add(self.layout)\n        self.update_pyramid()\n\n    def pyramid_plot(self):\n        from bokeh.models import (Plot, DataRange1d, LinearAxis, Grid,\n                                  Legend, SingleIntervalTicker)\n        from bokeh.models.glyphs import Quad\n\n        xdr = DataRange1d(sources=[self.source_pyramid.columns(\"male\"),\n                                   self.source_pyramid.columns(\"female\")])\n        ydr = DataRange1d(sources=[self.source_pyramid.columns(\"groups\")])\n\n        self.plot = Plot(title=\"Widgets\", x_range=xdr, y_range=ydr,\n                         plot_width=600, plot_height=600)\n\n        xaxis = LinearAxis()\n        self.plot.add_layout(xaxis, 'below')\n        yaxis = LinearAxis(ticker=SingleIntervalTicker(interval=5))\n        self.plot.add_layout(yaxis, 'left')\n\n        self.plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))\n        self.plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))\n\n        male_quad = Quad(left=\"male\", right=0, bottom=\"groups\", top=\"shifted\",\n                         fill_color=\"#3B8686\")\n        male_quad_glyph = self.plot.add_glyph(self.source_pyramid, male_quad)\n\n        female_quad = Quad(left=0, right=\"female\", bottom=\"groups\", top=\"shifted\",\n                           fill_color=\"#CFF09E\")\n        female_quad_glyph = self.plot.add_glyph(self.source_pyramid, female_quad)\n\n        self.plot.add_layout(Legend(legends=dict(Male=[male_quad_glyph],\n                                                 Female=[female_quad_glyph])))\n\n    def on_year_change(self, obj, attr, old, new):\n        self.year = int(new)\n        self.update_pyramid()\n\n    def on_location_change(self, obj, attr, old, new):\n        self.location = new\n        self.update_pyramid()\n\n    def create_layout(self):\n        from bokeh.models.widgets import Select, HBox, VBox\n\n        years = list(map(str, sorted(self.df.Year.unique())))\n        locations = sorted(self.df.Location.unique())\n\n        year_select = Select(title=\"Year:\", value=\"2010\", options=years)\n        location_select = Select(title=\"Location:\", value=\"World\", options=locations)\n\n        year_select.on_change('value', self.on_year_change)\n        location_select.on_change('value', self.on_location_change)\n\n        controls = HBox(year_select, location_select)\n        self.layout = VBox(controls, self.plot)\n\n    def update_pyramid(self):\n        pyramid = self.df[(self.df.Location == self.location) & (self.df.Year == self.year)]\n\n        male = pyramid[pyramid.Sex == \"Male\"]\n        female = pyramid[pyramid.Sex == \"Female\"]\n\n        total = male.Value.sum() + female.Value.sum()\n\n        male_percent = -male.Value / total\n        female_percent = female.Value / total\n\n        groups = male.AgeGrpStart.tolist()\n        shifted = groups[1:] + [groups[-1] + 5]\n\n        self.source_pyramid.data = dict(\n            groups=groups,\n            shifted=shifted,\n            male=male_percent,\n            female=female_percent,\n        )\n        self.session.store_document(self.document)\n\n\ndef update_population(plot):\n    while True:\n        plot.session.load_document(plot.document)\n        time.sleep(0.1)\n\nif __name__ == '__main__':\n    app.run(debug=True)\n", "path": "examples/embed/slideshow/app_reveal.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"\nIn this example, we want to show you how you can take isolated blocks of code\n(featuring different kinds of Bokeh visualizations) and rearrange them in a\nbigger (encompassing) flask-based application without losing the independence\nof each example. This is the reason of some weirdness through the code.\nWe are using this \"building blocks\" approach here because we believe it has some\nconceptual advantages for people trying to quickly understand, and more\nimportantly, use the embed API, in a more complex way than just a simple script.\n\"\"\"\nimport time\nfrom threading import Thread\n\nimport numpy as np\nimport scipy.special\n\nfrom bokeh.embed import autoload_server\nfrom bokeh.models import GlyphRenderer\nfrom bokeh.plotting import cursession, figure, output_server, push\n\nfrom flask import Flask, render_template\napp = Flask(__name__)\n\n@app.route('/')\ndef render_plot():\n    \"\"\"\n    Get the script tags from each plot object and \"insert\" them into the template.\n\n    This also starts different threads for each update function, so you can have\n    a non-blocking update.\n    \"\"\"\n    dist_plot, dist_session = distribution()\n    dist_tag = autoload_server(dist_plot, dist_session)\n\n    anim_plot, anim_session = animated()\n    anim_tag = autoload_server(anim_plot, anim_session)\n    # for update_animation as target we need to pass the anim_plot and anim_session as args\n    thread = Thread(target=update_animation, args=(anim_plot, anim_session))\n    thread.start()\n\n    pop = Population()\n    pop_tag = autoload_server(pop.layout, pop.session)\n    # for update_population as target we need to pass the pop instance as args\n    thread = Thread(target=update_population, args=(pop,))\n    thread.start()\n\n    return render_template('app_plot.html', tag1=dist_tag, tag2=anim_tag, tag3=pop_tag)\n\n\ndef distribution():\n\n    mu, sigma = 0, 0.5\n\n    measured = np.random.normal(mu, sigma, 1000)\n    hist, edges = np.histogram(measured, density=True, bins=20)\n\n    x = np.linspace(-2, 2, 1000)\n    pdf = 1 / (sigma * np.sqrt(2 * np.pi)) * np.exp(-(x - mu) ** 2 / (2 * sigma ** 2))\n    cdf = (1 + scipy.special.erf((x - mu) / np.sqrt(2 * sigma ** 2))) / 2\n\n    output_server(\"distribution_reveal\")\n\n    p = figure(title=\"Interactive plots\",\n               background_fill=\"#E5E5E5\")\n    p.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],\n           fill_color=\"#333333\", line_color=\"#E5E5E5\", line_width=3)\n\n    # Use `line` renderers to display the PDF and CDF\n    p.line(x, pdf, line_color=\"#348abd\", line_width=8, alpha=0.7, legend=\"PDF\")\n    p.line(x, cdf, line_color=\"#7a68a6\", line_width=8, alpha=0.7, legend=\"CDF\")\n\n    p.legend.orientation = \"top_left\"\n\n    p.xaxis.axis_label = 'x'\n    p.xgrid[0].grid_line_color = \"white\"\n    p.xgrid[0].grid_line_width = 3\n\n    p.yaxis.axis_label = 'Pr(x)'\n    p.ygrid[0].grid_line_color = \"white\"\n    p.ygrid[0].grid_line_width = 3\n\n    push()\n\n    return p, cursession()\n\n\ndef animated():\n\n    from numpy import pi, cos, sin, linspace\n\n    N = 50 + 1\n    r_base = 8\n    theta = linspace(0, 2 * pi, N)\n    r_x = linspace(0, 6 * pi, N - 1)\n    rmin = r_base - cos(r_x) - 1\n    rmax = r_base + sin(r_x) + 1\n\n    colors = [\"FFFFCC\", \"#C7E9B4\", \"#7FCDBB\", \"#41B6C4\", \"#2C7FB8\",\n              \"#253494\", \"#2C7FB8\", \"#41B6C4\", \"#7FCDBB\", \"#C7E9B4\"] * 5\n\n    output_server(\"animated_reveal\")\n\n    p = figure(title=\"Animations\", x_range=[-11, 11], y_range=[-11, 11])\n\n    p.annular_wedge(\n        0, 0, rmin, rmax, theta[:-1], theta[1:],\n        inner_radius_units=\"data\",\n        outer_radius_units=\"data\",\n        fill_color=colors,\n        line_color=\"black\",\n    )\n\n    push()\n\n    return p, cursession()\n\n\ndef update_animation(plot, session):\n\n    from numpy import roll\n\n    renderer = plot.select(dict(type=GlyphRenderer))\n    ds = renderer[0].data_source\n\n    while True:\n\n        rmin = ds.data[\"inner_radius\"]\n        rmin = roll(rmin, 1)\n        ds.data[\"inner_radius\"] = rmin\n\n        rmax = ds.data[\"outer_radius\"]\n        rmax = roll(rmax, -1)\n        ds.data[\"outer_radius\"] = rmax\n\n        cursession().store_objects(ds)\n        time.sleep(0.1)\n\n\nclass Population(object):\n\n    year = 2010\n    location = \"World\"\n\n    def __init__(self):\n        from bokeh.models import ColumnDataSource\n        from bokeh.document import Document\n        from bokeh.session import Session\n        from bokeh.sampledata.population import load_population\n\n        self.document = Document()\n        self.session = Session()\n        self.session.use_doc('population_reveal')\n        self.session.load_document(self.document)\n\n        self.df = load_population()\n        self.source_pyramid = ColumnDataSource(data=dict())\n\n        # just render at the initialization\n        self._render()\n\n    def _render(self):\n        self.pyramid_plot()\n        self.create_layout()\n        self.document.add(self.layout)\n        self.update_pyramid()\n\n    def pyramid_plot(self):\n        from bokeh.models import (Plot, DataRange1d, LinearAxis, Grid,\n                                  Legend, SingleIntervalTicker)\n        from bokeh.models.glyphs import Quad\n\n        xdr = DataRange1d(sources=[self.source_pyramid.columns(\"male\"),\n                                   self.source_pyramid.columns(\"female\")])\n        ydr = DataRange1d(sources=[self.source_pyramid.columns(\"groups\")])\n\n        self.plot = Plot(title=\"Widgets\", x_range=xdr, y_range=ydr,\n                         plot_width=600, plot_height=600)\n\n        xaxis = LinearAxis()\n        self.plot.add_layout(xaxis, 'below')\n        yaxis = LinearAxis(ticker=SingleIntervalTicker(interval=5))\n        self.plot.add_layout(yaxis, 'left')\n\n        self.plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))\n        self.plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))\n\n        male_quad = Quad(left=\"male\", right=0, bottom=\"groups\", top=\"shifted\",\n                         fill_color=\"#3B8686\")\n        male_quad_glyph = self.plot.add_glyph(self.source_pyramid, male_quad)\n\n        female_quad = Quad(left=0, right=\"female\", bottom=\"groups\", top=\"shifted\",\n                           fill_color=\"#CFF09E\")\n        female_quad_glyph = self.plot.add_glyph(self.source_pyramid, female_quad)\n\n        self.plot.add_layout(Legend(legends=dict(Male=[male_quad_glyph],\n                                                 Female=[female_quad_glyph])))\n\n    def on_year_change(self, obj, attr, old, new):\n        self.year = int(new)\n        self.update_pyramid()\n\n    def on_location_change(self, obj, attr, old, new):\n        self.location = new\n        self.update_pyramid()\n\n    def create_layout(self):\n        from bokeh.models.widgets import Select, HBox, VBox\n\n        years = list(map(str, sorted(self.df.Year.unique())))\n        locations = sorted(self.df.Location.unique())\n\n        year_select = Select(title=\"Year:\", value=\"2010\", options=years)\n        location_select = Select(title=\"Location:\", value=\"World\", options=locations)\n\n        year_select.on_change('value', self.on_year_change)\n        location_select.on_change('value', self.on_location_change)\n\n        controls = HBox(year_select, location_select)\n        self.layout = VBox(controls, self.plot)\n\n    def update_pyramid(self):\n        pyramid = self.df[(self.df.Location == self.location) & (self.df.Year == self.year)]\n\n        male = pyramid[pyramid.Sex == \"Male\"]\n        female = pyramid[pyramid.Sex == \"Female\"]\n\n        total = male.Value.sum() + female.Value.sum()\n\n        male_percent = -male.Value / total\n        female_percent = female.Value / total\n\n        groups = male.AgeGrpStart.tolist()\n        shifted = groups[1:] + [groups[-1] + 5]\n\n        self.source_pyramid.data = dict(\n            groups=groups,\n            shifted=shifted,\n            male=male_percent,\n            female=female_percent,\n        )\n        self.session.store_document(self.document)\n\n\ndef update_population(plot):\n    while True:\n        plot.session.load_document(plot.document)\n        time.sleep(0.1)\n\nif __name__ == '__main__':\n    app.run(debug=True)\n", "path": "examples/embed/slideshow/app_reveal.py"}]}