from bokeh.sampledata.sprint import sprint
sprint[:10]

"""
Explanation: <table style="float:left; border:none">
   <tr style="border:none">
       <td style="border:none">
           <a href="http://bokeh.pydata.org/">     
           <img 
               src="http://bokeh.pydata.org/en/latest/_static/bokeh-transparent.png" 
               style="width:70px"
           >
           </a>    
       </td>
       <td style="border:none">
           <h1>Bokeh Tutorial &mdash; <tt style="display:inline">bokeh.models</tt> interface</h1>
       </td>
   </tr>
</table>

Models
NYTimes interactive chart Usain Bolt vs. 116 years of Olympic sprinters
The first thing we need is to get the data. The data for this chart is located in the bokeh.sampledata module as a Pandas DataFrame. You can see the first ten rows below:?
End of explanation
"""


from bokeh.io import output_notebook, show
from bokeh.models.glyphs import Circle, Text
from bokeh.models import ColumnDataSource, Range1d, DataRange1d, Plot

output_notebook()

"""
Explanation: Next we import some of the Bokeh models that need to be assembled to make a plot. At a minimum, we need to start with Plot, the glyphs (Circle and Text) we want to display, as well as ColumnDataSource to hold the data and range obejcts to set the plot bounds.
End of explanation
"""


abbrev_to_country = {
    "USA": "United States",
    "GBR": "Britain",
    "JAM": "Jamaica",
    "CAN": "Canada",
    "TRI": "Trinidad and Tobago",
    "AUS": "Australia",
    "GER": "Germany",
    "CUB": "Cuba",
    "NAM": "Namibia",
    "URS": "Soviet Union",
    "BAR": "Barbados",
    "BUL": "Bulgaria",
    "HUN": "Hungary",
    "NED": "Netherlands",
    "NZL": "New Zealand",
    "PAN": "Panama",
    "POR": "Portugal",
    "RSA": "South Africa",
    "EUA": "United Team of Germany",
}

gold_fill   = "#efcf6d"
gold_line   = "#c8a850"
silver_fill = "#cccccc"
silver_line = "#b0b0b1"
bronze_fill = "#c59e8a"
bronze_line = "#98715d"

fill_color = { "gold": gold_fill, "silver": silver_fill, "bronze": bronze_fill }
line_color = { "gold": gold_line, "silver": silver_line, "bronze": bronze_line }

def selected_name(name, medal, year):
    return name if medal == "gold" and year in [1988, 1968, 1936, 1896] else None

t0 = sprint.Time[0]

sprint["Abbrev"]       = sprint.Country
sprint["Country"]      = sprint.Abbrev.map(lambda abbr: abbrev_to_country[abbr])
sprint["Medal"]        = sprint.Medal.map(lambda medal: medal.lower())
sprint["Speed"]        = 100.0/sprint.Time
sprint["MetersBack"]   = 100.0*(1.0 - t0/sprint.Time)
sprint["MedalFill"]    = sprint.Medal.map(lambda medal: fill_color[medal])
sprint["MedalLine"]    = sprint.Medal.map(lambda medal: line_color[medal])
sprint["SelectedName"] = sprint[["Name", "Medal", "Year"]].apply(tuple, axis=1).map(lambda args: selected_name(*args))

source = ColumnDataSource(sprint)

"""
Explanation: Setting up Data
End of explanation
"""


plot_options = dict(plot_width=800, plot_height=480, toolbar_location=None, 
                    outline_line_color=None, title = "Usain Bolt vs. 116 years of Olympic sprinters")

radius = dict(value=5, units="screen")
medal_glyph = Circle(x="MetersBack", y="Year", radius=radius, fill_color="MedalFill", 
                     line_color="MedalLine", fill_alpha=0.5)

athlete_glyph = Text(x="MetersBack", y="Year", x_offset=10, text="SelectedName",
    text_align="left", text_baseline="middle", text_font_size="9pt")

no_olympics_glyph = Text(x=7.5, y=1942, text=["No Olympics in 1940 or 1944"],
    text_align="center", text_baseline="middle",
    text_font_size="9pt", text_font_style="italic", text_color="silver")


xdr = Range1d(start=sprint.MetersBack.max()+2, end=0)  # +2 is for padding
ydr = DataRange1d(range_padding=0.05)  

plot = Plot(x_range=xdr, y_range=ydr, **plot_options)
plot.add_glyph(source, medal_glyph)
plot.add_glyph(source, athlete_glyph)
plot.add_glyph(no_olympics_glyph)

show(plot)

"""
Explanation: Basic Plot with Glyphs
End of explanation
"""


from bokeh.models import Grid, LinearAxis, SingleIntervalTicker

xdr = Range1d(start=sprint.MetersBack.max()+2, end=0)  # +2 is for padding
ydr = DataRange1d(range_padding=0.05)  

plot = Plot(x_range=xdr, y_range=ydr, **plot_options)
plot.add_glyph(source, medal_glyph)
plot.add_glyph(source, athlete_glyph)
plot.add_glyph(no_olympics_glyph)

xticker = SingleIntervalTicker(interval=5, num_minor_ticks=0)
xaxis = LinearAxis(ticker=xticker, axis_line_color=None, major_tick_line_color=None,
                   axis_label="Meters behind 2012 Bolt", axis_label_text_font_size="10pt", 
                   axis_label_text_font_style="bold")
plot.add_layout(xaxis, "below")

xgrid = Grid(dimension=0, ticker=xaxis.ticker, grid_line_dash="dashed")
plot.add_layout(xgrid)

yticker = SingleIntervalTicker(interval=12, num_minor_ticks=0)
yaxis = LinearAxis(ticker=yticker, major_tick_in=-5, major_tick_out=10)
plot.add_layout(yaxis, "right")

show(plot)

"""
Explanation: Adding Axes and Grids
End of explanation
"""


from bokeh.models import HoverTool

tooltips = """
<div>
    <span style="font-size: 15px;">@Name</span>&nbsp;
    <span style="font-size: 10px; color: #666;">(@Abbrev)</span>
</div>
<div>
    <span style="font-size: 17px; font-weight: bold;">@Time{0.00}</span>&nbsp;
    <span style="font-size: 10px; color: #666;">@Year</span>
</div>
<div style="font-size: 11px; color: #666;">@{MetersBack}{0.00} meters behind</div>
"""

xdr = Range1d(start=sprint.MetersBack.max()+2, end=0)  # +2 is for padding
ydr = DataRange1d(range_padding=0.05)  

plot = Plot(x_range=xdr, y_range=ydr, **plot_options)
medal = plot.add_glyph(source, medal_glyph)  # we need this renderer to configure the hover tool
plot.add_glyph(source, athlete_glyph)
plot.add_glyph(no_olympics_glyph)

xticker = SingleIntervalTicker(interval=5, num_minor_ticks=0)
xaxis = LinearAxis(ticker=xticker, axis_line_color=None, major_tick_line_color=None,
                   axis_label="Meters behind 2012 Bolt", axis_label_text_font_size="10pt", 
                   axis_label_text_font_style="bold")
plot.add_layout(xaxis, "below")

xgrid = Grid(dimension=0, ticker=xaxis.ticker, grid_line_dash="dashed")
plot.add_layout(xgrid)

yticker = SingleIntervalTicker(interval=12, num_minor_ticks=0)
yaxis = LinearAxis(ticker=yticker, major_tick_in=-5, major_tick_out=10)
plot.add_layout(yaxis, "right")

hover = HoverTool(tooltips=tooltips, renderers=[medal])
plot.add_tools(hover)

show(plot)

from bubble_plot import get_1964_data

def get_plot():
    return Plot(
        x_range=Range1d(1, 9), y_range=Range1d(20, 100),
        title="", plot_width=800, plot_height=400,
        outline_line_color=None, toolbar_location=None,
    )

df = get_1964_data()
df.head()

# EXERCISE: Add Circles to the plot from the data in `df`. 
# With `fertility` for the x coordinates, `life` for the y coordinates.

plot = get_plot()




# EXERCISE: Color the circles by region_color & change the size of the color by population




# EXERCISE: Add axes and grid lines



# EXERCISE: Manually add a legend using Circle & Text. The color key is as follows 

region_name_and_color = [
    ('America', '#3288bd'),
    ('East Asia & Pacific', '#99d594'),
    ('Europe & Central Asia', '#e6f598'),
    ('Middle East & North Africa', '#fee08b'),
    ('South Asia', '#fc8d59'),
    ('Sub-Saharan Africa', '#d53e4f')
]

"""
Explanation: Adding a Hover Tool
End of explanation
"""


