Problem of the range of y axis when the source changes

Hi All,

I’m facing a problem with the range of y-axis.
I want to show different plots with their data in one figure.
However, it seems that there’re some problems with range of y-axis.

When i use the data of one set of data, it looks like:
image
This figure looks very weird. I know that can use figure tools to resize the axis. Is there any way to make it automatically to show the correct scale?
The maximum value of this data is about 3000, and the minimum value is about 500

But for another set of data (sorry, I cannot upload the second picture, only one picture is allowed)
Anyway, the figure looks good and the scale is very normal.

Thank you!
BTW, do I need to put my code here?

Here is my code ---------------------------------------------
# create input controls
code_input = TextInput(title = ‘code’(e.g:000001.XSHE)’)
ticker_swl1 = Select(value=‘all’, options=options1,title = ‘level 1’)
ticker_swl3 = Select(value=‘all’, options=options3,title = ‘level 3’)
ticker_picture = Select(value=‘total market cap’, options=picture_option,title = ‘select a factor’)

def plot_data_transfer(data,var_name):
    df = data
    df = df[['date',var_name]]
    df = df.rename(columns={'date':'x',var_name:'y'})
    df.x = pd.to_datetime(df.x)
    return df
# input stock
def select_stock():
    code_val = code_input.value#.strip()
    selected = df
    if code_val != '':
        selected = df[df.code.str.contains(code_val)]
        
    return selected

# select industry
def select_industry_sw1():
    industry_val = ticker_swl1.value
    selected = df
    
    if industry_val == 'all':
        selected_df = selected
    else:
        selected_df = df[df['level 1'] == industry_val]
    return selected_df

def select_industry_sw3():
    industry_val = ticker_swl3.value
    selected = df
    
    if industry_val == 'all':
        selected_df = selected
    else:
        selected_df = df[df['level 3'] == industry_val]
    return selected_df

# update single_stock
def update_single_stock():
    code_val = code_input.value
    stock_df = pd.read_csv('data/%s.csv'%code_val,index_col = 0)
    stock_df = stock_df.drop('code',axis = 1)
    formater = lambda x:'%.3f' %x
    stock_df.iloc[:,1:] = stock_df.iloc[:,1:].applymap(formater)
    return stock_df

# plot
def make_plot():
    plot_val = ticker_picture.value
    plot = figure(x_axis_type="datetime",plot_width=500,plot_height = 400,
                  tools="pan,box_zoom,wheel_zoom,reset",toolbar_location="below",
                  y_range = DataRange1d()) 
    plot.line('x', 'y', source = source_3)
    plot.title.text = plot_val

    return plot
    
# source
source_1 = ColumnDataSource(df)
source_2 = ColumnDataSource(single_stock_df)
source_3 = ColumnDataSource(plot_data_transfer(single_stock_df,'total market cap'))

# callback
def stock_select(attr,old,new):
    df1 = select_stock()
    df2 = update_single_stock()
    source_1.data = df1
    source_2.data = df2
    source_3.data = plot_data_transfer(df2,ticker_picture.value)
    
def industry_change_sw1(attr,old,new):
    df0 = select_industry_sw1()
    source_1.data = df0
    if new != 'all':
        ticker_swl3.options = list(stock[['level 1','level 3']].loc[stock['level 1']==new]['level 3'].unique())
    else:
        ticker_swl3.options = ['all']
        
def industry_change_sw3(attr,old,new):
    df0 = select_industry_sw3()
    source_1.data = df0

def plot_change(attrname, old, new):
    plot_val = ticker_picture.value
    plot.title.text = plot_val
    
    df0 = update_single_stock()
    df0 = plot_data_transfer(df0,plot_val)
    source_3.data = df0
    
    start = source_3.data['y'].min()
    end = source_3.data['y'].max()
    plot.y_range = DataRange1d(start= start,end = end)

    
#change of interactive function
code_input.on_change('value',stock_select)
ticker_swl1.on_change('value',industry_change_sw1)
ticker_swl3.on_change('value',industry_change_sw3)
ticker_picture.on_change('value', plot_change)

#set attributte of interactive function
inputs = column(code_input, width  = 300, height = 100)
ticker1 = column(ticker_swl1, width = 300, height = 100)
ticker2 = column(ticker_swl3, width = 300, height = 100)
ticker3 = column(ticker_picture, width = 300, height = 100)


columns_1 = [TableColumn(field = i, title = i, width = 500) for i in df.columns[:]]
columns_2 = [TableColumn(field = i, title = i, width = 450) for i in single_stock_df.columns[:]]

data_table_1 = DataTable(source=source_1, columns=columns_1, height = 300, width = 1600)
data_table_2 = DataTable(source=source_2, columns=columns_2, height = 300, width = 1200)
plot = make_plot()

#set the layout
l = layout([
    [data_table_1],
    [inputs,ticker1,ticker2,ticker_picture],
    [data_table_2,plot],
])

curdoc().add_root(l)
curdoc().title = 'Stocks'

Hi @Li_Shen,

The plot really should be auto-adjusting the range, but if necessary you can pass in an arg when you create the figure, something like y_range=(500,3000). It’s not clear from the image why it’s not automatically accommodating your line. Yes, your code might help us figure it out.

Hi Carolyn,

Thanks for your advice. Actually, the range of y could be (500,3000) for this data source, but it could be (0,1) for another data source.

If you want automatic ranging based on the data, you should not set explicit start and end values as you are doing above. If you manually set start and end then Bokeh assumes you know what you want, and those values you set will take precedence over any automatic ranging.

For the most part, if you want auto-ranging you should simply not ever set y_range at all. It’s unusual to set e.g. y_range = DataRange1d() since a DataRange1d is already what you will get by default.

1 Like

Hi Bryan,

I followed your instruction and deledted y_range = DataRange1d() and plot.y_range = DataRange1d(start= start,end = end).
However, the figure is still weird like below:

for your reference the data set is:
2010/3/31 720.4606
2010/6/30 610.2259
2010/9/30 565.2692
2010/12/31 550.2837
2011/3/31 560.3902
2011/6/30 594.8918
2011/9/30 821.7854
2011/12/30 798.7303
2012/3/30 804.8784
2012/6/29 776.6999
2012/9/28 672.6959
2012/12/31 820.7607
2013/3/29 1030.8181
2013/6/28 817.2769
2013/9/30 973.8464
2013/12/31 1004.1767
2014/3/31 1025.3843
2014/6/30 1132.2072
2014/9/30 1158.4843
2014/12/31 1809.7032
2015/3/31 1799.4209
2015/6/30 2080.4814
2015/9/30 1500.9801
2015/12/31 1715.6104
2016/3/31 1522.4431
2016/6/30 1493.8258
2016/9/30 1557.3563
2016/12/30 1562.5074
2017/3/31 1574.5267
2017/6/30 1612.3016
2017/9/29 1907.6327
2017/12/29 2283.6648
2018/3/30 1871.5748
2018/6/29 1560.7904
2018/9/28 1897.3304
2018/12/28 1610.5846
2019/3/29 2201.2466
2019/6/28 2366.0828
2019/9/30 3025.3826
2019/12/31 3192.2734
2020/3/31 2483.9575
2020/6/30 2483.9575
2020/9/30 2943.8777