title: python bokeh dynamically update categorical x_range
body: <p>I want to create a candlestick plot in bokeh and dynamically update the x-axis according to user input through a MultiSelect widget. Basically the user will choose a few items in the MultiSelect and then I would like those to become the values of the x axis. I already have set up the MultiSelect widget and confirmed that it is working by attaching a DataTable to the MultiSelect and having it update accordingly (which it does). I just need help retrieving the values from the MultiSelect widget and setting them as my plot.x_range. Based on a few github/issues posts (like this one: <a href="https://github.com/bokeh/bokeh/issues/4022" rel="nofollow noreferrer">https://github.com/bokeh/bokeh/issues/4022</a>) I tried using a FactorRange, but it isn't working. Currently the behavior is the x axis labels stay set to the values that are set during the initial configuration of the MultiSelect ('aaa' and 'bbb'), and don't change when I choose different values in the MultiSelect widget.</p>
  
  <p>Here's a code sample:</p>
  
  <pre><code>### SET UP SOURCE DF INFO ###
  tab2_source = ColumnDataSource(df)
  tab2_original_source = ColumnDataSource(df)
  columns_t2 = [TableColumn(field='Gene', title='Gene'), TableColumn(field='row_min', title='min'), TableColumn(field='row_max', title='max'), 
               TableColumn(field='quantile_25', title='25th quantile'), TableColumn(field='quantile_50', title='50th quantile'), TableColumn(field='quantile_75', title='75th quantile')]
  data_table_t2 = DataTable(source=tab2_source, columns=columns_t2, reorderable=False)
  
  ### STUFF FOR THE WIDGETS ###
  # customJS stuff
  tab2_callback_code = """
  var t2_data = tab2_source.data;
  var t2_original_data = tab2_original_source.data;
  var gene_t2 = gene_select_obj_t2.value;
  console.log("gene: " + gene_t2);
  for (var key in t2_original_data) {
      t2_data[key] = [];
      for (var i = 0; i &lt; t2_original_data['Gene'].length; ++i) {
          if (t2_original_data['Gene'][i] === gene_t2[0] || t2_original_data['Gene'][i] === gene_t2[1]) {
              t2_data[key].push(t2_original_data[key][i]);
          }
      }
  }
  
  tab2_source.change.emit();
  target_obj_t2.change.emit();
  """
  
  # make drop-down selectors
  select_gene_t2 = MultiSelect(title = "Select up to 2 Genes to View:", value=['aaa', 'bbb'], options=list(df.Gene.unique()))
  
  # define the callback objects now that the select widgets exist
  tab2_callback = CustomJS(
      args=dict(tab2_source=tab2_source,
               tab2_original_source=tab2_original_source,
               gene_select_obj_t2=select_gene_t2,
               target_obj_t2=data_table_t2),
      code=tab2_callback_code)
  
  # connect the callbacks to the filter widgets
  select_gene_t2.js_on_change('value', tab2_callback)
  
  
  ## PLOTTING ##
  p2 = figure(plot_width=500, plot_height=400, title='Avg Gene Exp', y_range=(-2,12), x_range=FactorRange())
  p2.x_range.factors = list(select_gene_t2.value)
  p2.vbar(x='Gene', top='quantile_75', bottom='quantile_25', source=tab2_source, width=0.5, fill_color="#D5E1DD", line_color="black")
  tab2 = Panel(child=column(select_gene_t2, p2, data_table_t2), title="Exp by Gene")
  tabs = Tabs(tabs=[tab2])
  save(tabs)
  
  </code></pre>