@@ -194,6 +194,8 @@ options.Rectangles = Options('style', line_color='black')
 
 # Rasters
 options.Image = Options('style', cmap=dflt_cmap)
+options.Image = Options('plot', clipping_colors={'min': 'transparent',
+                                                 'max': 'transparent'})
 options.Raster = Options('style', cmap=dflt_cmap)
 options.QuadMesh = Options('style', cmap=dflt_cmap, line_alpha=0)
 options.HeatMap = Options('style', cmap='RdYlBu_r', annular_line_alpha=0,
from __future__ import absolute_import, division, unicode_literals

import numpy as np

from bokeh.palettes import all_palettes
from param import concrete_descendents

from ...core import (Store, Overlay, NdOverlay, Layout, AdjointLayout,
                     GridSpace, GridMatrix, NdLayout, config)
from ...element import (Curve, Points, Scatter, Image, Raster, Path,
                        RGB, Histogram, Spread, HeatMap, Contours, Bars,
                        Box, Bounds, Ellipse, Polygons, BoxWhisker, Arrow,
                        ErrorBars, Text, HLine, VLine, HSpan, VSpan, Spline, Spikes,
                        Table, ItemTable, Area, HSV, QuadMesh, VectorField,
                        Graph, Nodes, EdgePaths, Distribution, Bivariate,
                        TriMesh, Violin, Chord, Div, HexTiles, Labels, Sankey,
                        Tiles, Segments, Slope, Rectangles)
from ...core.options import Options, Cycle, Palette
try:
    from ...interface import DFrame
except:
    DFrame = None

from .annotation import (
    TextPlot, LineAnnotationPlot, BoxAnnotationPlot, SplinePlot, ArrowPlot,
    DivPlot, LabelsPlot, SlopePlot
)
from ..plot import PlotSelector
from ..util import fire
from .callbacks import Callback # noqa (API import)
from .element import OverlayPlot, ElementPlot
from .chart import (PointPlot, CurvePlot, SpreadPlot, ErrorPlot, HistogramPlot,
                    SideHistogramPlot, BarPlot, SpikesPlot, SideSpikesPlot,
                    AreaPlot, VectorFieldPlot)
from .geometry import SegmentPlot, RectanglesPlot
from .graphs import GraphPlot, NodePlot, TriMeshPlot, ChordPlot
from .heatmap import HeatMapPlot, RadialHeatMapPlot
from .hex_tiles import HexTilesPlot
from .path import PathPlot, PolygonPlot, ContourPlot
from .plot import GridPlot, LayoutPlot, AdjointLayoutPlot
from .raster import RasterPlot, RGBPlot, HSVPlot, QuadMeshPlot
from .renderer import BokehRenderer
from .sankey import SankeyPlot
from .stats import DistributionPlot, BivariatePlot, BoxWhiskerPlot, ViolinPlot
from .tabular import TablePlot
from .tiles import TilePlot
from .util import bokeh_version # noqa (API import)


Store.renderers['bokeh'] = BokehRenderer.instance()

if len(Store.renderers) == 1:
    Store.set_current_backend('bokeh')

associations = {Overlay: OverlayPlot,
                NdOverlay: OverlayPlot,
                GridSpace: GridPlot,
                GridMatrix: GridPlot,
                AdjointLayout: AdjointLayoutPlot,
                Layout: LayoutPlot,
                NdLayout: LayoutPlot,

                # Charts
                Curve: CurvePlot,
                Bars: BarPlot,
                Points: PointPlot,
                Scatter: PointPlot,
                ErrorBars: ErrorPlot,
                Spread: SpreadPlot,
                Spikes: SpikesPlot,
                Area: AreaPlot,
                VectorField: VectorFieldPlot,
                Histogram: HistogramPlot,

                # Rasters
                Image: RasterPlot,
                RGB: RGBPlot,
                HSV: HSVPlot,
                Raster: RasterPlot,
                HeatMap: PlotSelector(HeatMapPlot.is_radial,
                                      {True: RadialHeatMapPlot,
                                       False: HeatMapPlot},
                                      True),
                QuadMesh: QuadMeshPlot,

                # Paths
                Path: PathPlot,
                Contours: ContourPlot,
                Path:     PathPlot,
                Box:      PathPlot,
                Bounds:   PathPlot,
                Ellipse:  PathPlot,
                Polygons: PolygonPlot,

                # Geometry
                Rectangles:    RectanglesPlot,
                Segments: SegmentPlot,

                # Annotations
                HLine: LineAnnotationPlot,
                VLine: LineAnnotationPlot,
                HSpan: BoxAnnotationPlot,
                VSpan: BoxAnnotationPlot,
                Slope: SlopePlot,
                Text: TextPlot,
                Labels: LabelsPlot,
                Spline: SplinePlot,
                Arrow: ArrowPlot,
                Div: DivPlot,
                Tiles: TilePlot,

                # Graph Elements
                Graph: GraphPlot,
                Chord: ChordPlot,
                Nodes: NodePlot,
                EdgePaths: PathPlot,
                TriMesh: TriMeshPlot,
                Sankey: SankeyPlot,

                # Tabular
                Table: TablePlot,
                ItemTable: TablePlot,

                # Statistics
                Distribution: DistributionPlot,
                Bivariate: BivariatePlot,
                BoxWhisker: BoxWhiskerPlot,
                Violin: ViolinPlot,
                HexTiles: HexTilesPlot}


if DFrame is not None:
    associations[DFrame] = TablePlot

Store.register(associations, 'bokeh')

if config.no_padding:
    for plot in concrete_descendents(ElementPlot).values():
        plot.padding = 0

# Raster types, Path types and VectorField should have frames
for framedcls in [VectorFieldPlot, ContourPlot, PathPlot, PolygonPlot,
                  RasterPlot, RGBPlot, HSVPlot, QuadMeshPlot, HeatMapPlot]:
    framedcls.show_frame = True

AdjointLayoutPlot.registry[Histogram] = SideHistogramPlot
AdjointLayoutPlot.registry[Spikes] = SideSpikesPlot

point_size = np.sqrt(6) # Matches matplotlib default

# Register bokeh.palettes with Palette and Cycle
def colormap_generator(palette):
    return lambda value: palette[int(value*(len(palette)-1))]

Palette.colormaps.update({name: colormap_generator(p[max(p.keys())])
                          for name, p in all_palettes.items()})

Cycle.default_cycles.update({name: p[max(p.keys())] for name, p in all_palettes.items()
                             if max(p.keys()) < 256})

dflt_cmap = 'fire'
all_palettes['fire'] = {len(fire): fire}

options = Store.options(backend='bokeh')

# Charts
options.Curve = Options('style', color=Cycle(), line_width=2)
options.BoxWhisker = Options('style', box_fill_color=Cycle(), whisker_color='black',
                             box_line_color='black', outlier_color='black')
options.Scatter = Options('style', color=Cycle(), size=point_size, cmap=dflt_cmap)
options.Points = Options('style', color=Cycle(), size=point_size, cmap=dflt_cmap)
options.Points = Options('plot', show_frame=True)
options.Histogram = Options('style', line_color='black', color=Cycle(), muted_alpha=0.2)
options.ErrorBars = Options('style', color='black')
options.Spread = Options('style', color=Cycle(), alpha=0.6, line_color='black', muted_alpha=0.2)
options.Bars = Options('style', color=Cycle(), line_color='black', bar_width=0.8, muted_alpha=0.2)

options.Spikes = Options('style', color='black', cmap='fire', muted_alpha=0.2)
options.Area = Options('style', color=Cycle(), alpha=1, line_color='black', muted_alpha=0.2)
options.VectorField = Options('style', color='black', muted_alpha=0.2)

# Paths
options.Contours = Options('plot', show_legend=True)
options.Contours = Options('style', color=Cycle(), cmap='viridis')
options.Path = Options('style', color=Cycle(), cmap='viridis')
options.Box = Options('style', color='black')
options.Bounds = Options('style', color='black')
options.Ellipse = Options('style', color='black')
options.Polygons = Options('style', color=Cycle(), line_color='black',
                           cmap='viridis')

# Geometries
options.Rectangles = Options('style', line_color='black')

# Rasters
options.Image = Options('style', cmap=dflt_cmap)
options.Raster = Options('style', cmap=dflt_cmap)
options.QuadMesh = Options('style', cmap=dflt_cmap, line_alpha=0)
options.HeatMap = Options('style', cmap='RdYlBu_r', annular_line_alpha=0,
                          xmarks_line_color="#FFFFFF", xmarks_line_width=3,
                          ymarks_line_color="#FFFFFF", ymarks_line_width=3)

# Annotations
options.HLine = Options('style', color=Cycle(), line_width=3, alpha=1)
options.VLine = Options('style', color=Cycle(), line_width=3, alpha=1)
options.Slope = Options('style', color=Cycle(), line_width=3, alpha=1)
options.VSpan = Options('style', color=Cycle(), alpha=0.5)
options.HSpan = Options('style', color=Cycle(), alpha=0.5)
options.Arrow = Options('style', arrow_size=10)
options.Labels = Options('style', text_align='center', text_baseline='middle')

# Graphs
options.Graph = Options(
    'style', node_size=15, node_color=Cycle(), node_line_color='black',
    node_nonselection_fill_color=Cycle(), node_hover_line_color='black',
    node_hover_fill_color='limegreen', node_nonselection_alpha=0.2,
    edge_nonselection_alpha=0.2, node_nonselection_line_color='black',
    edge_color='black', edge_line_width=2, edge_nonselection_line_color='black',
    edge_hover_line_color='limegreen'
)
options.TriMesh = Options(
    'style', node_size=5, node_line_color='black', node_color='white',
    edge_line_color='black', node_hover_fill_color='limegreen',
    edge_line_width=1, edge_hover_line_color='limegreen',
    edge_nonselection_alpha=0.2, edge_nonselection_line_color='black',
    node_nonselection_alpha=0.2,
)
options.TriMesh = Options('plot', tools=[])
options.Chord = Options('style', node_size=15, node_color=Cycle(),
                        node_line_color='black',
                        node_selection_fill_color='limegreen',
                        node_nonselection_fill_color=Cycle(),
                        node_hover_line_color='black',
                        node_nonselection_line_color='black',
                        node_selection_line_color='black',
                        node_hover_fill_color='limegreen',
                        node_nonselection_alpha=0.2,
                        edge_nonselection_alpha=0.1,
                        edge_line_color='black', edge_line_width=1,
                        edge_nonselection_line_color='black',
                        edge_hover_line_color='limegreen',
                        edge_selection_line_color='limegreen',
                        label_text_font_size='8pt')
options.Chord = Options('plot', xaxis=None, yaxis=None)
options.Nodes = Options('style', line_color='black', color=Cycle(),
                        size=20, nonselection_fill_color=Cycle(),
                        selection_fill_color='limegreen',
                        hover_fill_color='indianred')
options.Nodes = Options('plot', tools=['hover', 'tap'])
options.EdgePaths = Options('style', color='black', nonselection_alpha=0.2,
                            line_width=2, selection_color='limegreen',
                            hover_line_color='indianred')
options.EdgePaths = Options('plot', tools=['hover', 'tap'])
options.Sankey = Options(
    'plot', xaxis=None, yaxis=None, inspection_policy='edges',
    selection_policy='nodes', show_frame=False, width=1000, height=600
)
options.Sankey = Options(
    'style', node_nonselection_alpha=0.2, node_size=10, edge_nonselection_alpha=0.2,
    edge_fill_alpha=0.6, label_text_font_size='8pt', cmap='Category20',
    node_line_color='black', node_selection_line_color='black', node_hover_alpha=1,
    edge_hover_alpha=0.9
)


# Define composite defaults
options.GridMatrix = Options('plot', shared_xaxis=True, shared_yaxis=True,
                             xaxis=None, yaxis=None)

options.Overlay = Options('style', click_policy='mute')
options.NdOverlay = Options('style', click_policy='mute')
options.Curve = Options('style', muted_alpha=0.2)
options.Path = Options('style', muted_alpha=0.2)
options.Scatter = Options('style', muted_alpha=0.2)
options.Points = Options('style', muted_alpha=0.2)
options.Polygons = Options('style', muted_alpha=0.2)

# Statistics
options.Distribution = Options(
    'style', color=Cycle(), line_color='black', fill_alpha=0.5,
    muted_alpha=0.2
)
options.Violin = Options(
    'style', violin_fill_color=Cycle(), violin_line_color='black',
    violin_fill_alpha=0.5, stats_color='black', box_color='black',
    median_color='white', cmap='Category10'
)
options.HexTiles = Options('style', muted_alpha=0.2)

Why is 'max' transparent? I don't think we want to avoid seeing the maximum pixels; seems like those should be in another color sometimes (e.g. red for a colormap not including red), but it's hard to think of a use for them being transparent.