I have a linear Bokeh plot under Bokeh version 3.3.0. I would like to add a (scatter) plot on an additional x-axis with logarithmic scale. This is my code:
import pandas as pd
from bokeh.plotting import figure, show, ColumnDataSource
from bokeh.layouts import gridplot
from bokeh.models import LogAxis, LinearAxis, Label, LabelSet, Title, Range1d
# A simple dataframe with time, UTCs, altitude and two columns of imaginary data
df = pd.DataFrame([['2024-06-21 06:22:38', 605.968389, 0.994548, 3],
['2024-06-21 06:22:39', 616.009398, 0.983443, 4],
['2024-06-21 06:22:40', 624.630573, 0.973647, 1],
['2024-06-21 06:22:41', 633.476367, 1.017651, 2],
['2024-06-21 06:22:42', 642.322161, 5.017651, 2],
['2024-06-21 06:22:43', 650.268389, 30.726555, 4],
['2024-06-21 06:22:44', 659.559398, 89.2359, 5],
['2024-06-21 06:22:45', 665.630573, 6.92018, 3],
['2024-06-21 06:22:47', 673.476367, 0.69398, 2],
['2024-06-21 06:22:48', 685.322161, 0.770802, 1],
['2024-06-21 06:22:49', 697.155939, 0.856488, 0],
['2024-06-21 06:22:51', 716.763057, 0.934408, 3],
['2024-06-21 06:22:52', 722.012345, 7.865522, 2],
],
columns=['time', 'Altitude', 'log_data', 'linear_data'])
#Linear Plot with second x-axis in logarithmic scale
p = figure(title="Combined linear / log x-axes",
x_axis_label="Linear Data",
y_axis_label="Altitude / km",
x_axis_type='linear',
frame_height = 900,
frame_width = 650,
)
p.xaxis.axis_label_text_color = "red"
# linear data
p1 = p.line('linear_data',
'Altitude',
line_color='red',
line_width=2,
source = df)
# log data
p.add_layout(LinearAxis(x_range_name = "x2",
axis_label="Log data",
axis_label_text_color='blue',),
'below' )
p2 = p.scatter('log_data',
'Altitude',
line_color='blue',
line_width=2,
x_range_name = 'x2',
source = df)
# Range of additional x-axis:
p.extra_x_ranges = {"x2": Range1d(start = 0,
end = 115),
}
# Graphical output:
layout_p = gridplot([p], ncols=1, width=700, height=900)
show(layout_p)
I changed LinearAxis
into LogAxis
# log data
p.add_layout(LogAxis(x_range_name = "x2",
axis_label="Log data",
axis_label_text_color='blue',),
'below' )
but this caused the second axis to be displayed without any ticks and the scatter plot was still shown on a linear base. Any hint for me?
After another search, I finally found a solution. Once I had found it, it seemed logical that something was still missing:
In the header section, the following must also be imported: from bokeh.models import LogScale
And then the additional axis must be defined as a logarithmic scale: p.extra_x_scales['x2'] = LogScale()
I changed the code a bit to make the result easier to see:
the linear axis range is from 0 to 10 now
the logarithmic curve is now a line instead of a scatter plot
its starting range is 0,1 instead of 0
I also made the chart a bit smaller to save space ;-)
And here is the code:
import pandas as pd
from bokeh.plotting import figure, show, ColumnDataSource
from bokeh.layouts import gridplot
from bokeh.models import LogAxis, LogScale, LinearAxis, Label, LabelSet, Title, Range1d
# A simple dataframe with time, UTCs, altitude and two columns of imaginary data
df = pd.DataFrame([['2024-06-21 06:22:38', 605.968389, 0.994548, 3],
['2024-06-21 06:22:39', 616.009398, 0.983443, 4],
['2024-06-21 06:22:40', 624.630573, 0.973647, 1],
['2024-06-21 06:22:41', 633.476367, 1.017651, 2],
['2024-06-21 06:22:42', 642.322161, 5.017651, 2],
['2024-06-21 06:22:43', 650.268389, 30.726555, 4],
['2024-06-21 06:22:44', 659.559398, 89.2359, 5],
['2024-06-21 06:22:45', 665.630573, 6.92018, 3],
['2024-06-21 06:22:47', 673.476367, 0.69398, 2],
['2024-06-21 06:22:48', 685.322161, 0.770802, 1],
['2024-06-21 06:22:49', 697.155939, 0.856488, 0],
['2024-06-21 06:22:51', 716.763057, 0.934408, 3],
['2024-06-21 06:22:52', 722.012345, 7.865522, 2],
],
columns=['time', 'Altitude', 'log_data', 'linear_data'])
`#Linear Plot with second x-axis in logarithmic scale
p = figure(title="Combined linear / log x-axes",
x_axis_label="Linear Data",
y_axis_label="Altitude / km",
x_axis_type='linear',
x_range = (0,10),
frame_height = 600,
frame_width = 450,
)
p.xaxis.axis_label_text_color = "red"
# linear data
p1 = p.line('linear_data',
'Altitude',
#legend_label="Temperature",
line_color='red',
line_width=2,
source = df )
# log data
p.add_layout(LogAxis(x_range_name = "x2",
axis_label="Log data",
axis_label_text_color='blue',
),
#axis_line_color=f2),
'below' )
p2 = p.line('log_data',
'Altitude',
#legend_label="Relative Humidity",
line_color='blue',
line_width=2,
x_range_name = 'x2',
source = df)
# Range of additional x-axis:
p.extra_x_ranges = {"x2": Range1d(start = 0.1,
end = 115),
}
p.extra_x_scales['x2'] = LogScale()
layout_p = gridplot([p], ncols=1, width=400, height=500)
show(layout_p)
This is the resulting picture: