       [args..., opts] = args
       attrs = _.clone(opts)
       for param, i in params
-        attrs[param] = args[i]
-
-    source = attrs.source ? new models.ColumnDataSource()
-    delete attrs.source
+        do (param, i) ->
+          attrs[param] = args[i]
+
+    has_sglyph = _.any(_.keys(attrs), (key) -> key.startsWith("selection_"))
+    has_hglyph = _.any(_.keys(attrs), (key) -> key.startsWith("hover_"))
 
     glyph_ca   = @_pop_colors_and_alpha(cls, attrs)
     nsglyph_ca = @_pop_colors_and_alpha(cls, attrs, "nonselection_")
-    sglyph_ca  = @_pop_colors_and_alpha(cls, attrs, "selection_")
-    hglyph_ca  = @_pop_colors_and_alpha(cls, attrs, "hover_")
-
-    @_fixup_values(cls, source,   glyph_ca)
-    @_fixup_values(cls, source, nsglyph_ca)
-    @_fixup_values(cls, source,  sglyph_ca)
-    @_fixup_values(cls, source,  hglyph_ca)
-
-    @_fixup_values(cls, source, attrs)
+    sglyph_ca  = if has_sglyph then @_pop_colors_and_alpha(cls, attrs, "selection_") else {}
+    hglyph_ca  = if has_hglyph then @_pop_colors_and_alpha(cls, attrs, "hover_") else {}
+
+    data = {}
+
+    @_fixup_values(cls, data,   glyph_ca)
+    @_fixup_values(cls, data, nsglyph_ca)
+    @_fixup_values(cls, data,  sglyph_ca)
+    @_fixup_values(cls, data,  hglyph_ca)
+
+    @_fixup_values(cls, data, attrs)
 
     _make_glyph = (cls, attrs, extra_attrs) =>
       new cls(_.extend({}, attrs, extra_attrs))
 
     glyph   = _make_glyph(cls, attrs,   glyph_ca)
     nsglyph = _make_glyph(cls, attrs, nsglyph_ca)
-    sglyph  = _make_glyph(cls, attrs,  sglyph_ca)
-    hglyph  = _make_glyph(cls, attrs,  hglyph_ca)
+    sglyph  = if has_sglyph then _make_glyph(cls, attrs,  sglyph_ca) else null
+    hglyph  = if has_hglyph then _make_glyph(cls, attrs,  hglyph_ca) else null
+
+    source = attrs.source ? new models.ColumnDataSource()
+    source.data = _.extend({}, source.data, data)
+    delete attrs.source
 
     glyph_renderer = new models.GlyphRenderer({
       data_source:        source

      axis_label = x_axis_label
      if axis_label.length != 0
        xaxis.axis_label = axis_label
      xgrid = new models.Grid({plot: this, dimension: 0, ticker: xaxis.ticker})
      if x_axis_location == "above"
        this.above = (this.above ? []).concat([xaxis])
      else if x_axis_location == "below"
        this.below = (this.below ? []).concat([xaxis])

    y_axiscls = @_get_axis_class(y_axis_type, this.y_range)
    if y_axiscls?

  help:         () -> new models.HelpTool()
}

_with_default = (value, default_value) ->
  if value == undefined then default_value else value

class Figure extends models.Plot

  constructor: (attrs={}) ->
    attrs = _.clone(attrs)

    tools = _with_default(attrs.tools, _default_tools)
    delete attrs.tools

    attrs.x_range = @_get_range(attrs.x_range)
