I want to plot some financials data which have very wide ranges. At first I used linear axis, however due to the extreme ranges in both x and y axis...the plot end up unusable. I know there are outliers but I don't want to exclude them from the chart.
Hence I'm using log scale for both x and y axis. The log scale plot was successfully created, however it shows only the positive data...all the negative data is gone from the plot. Then I did a bit of searching around and I found in Bokeh github about forcing log axes to remain positive: https://github.com/bokeh/bokeh/issues/5550
With the info from github, is it really impossible to create a log scale which consists of negative values? What I want is the chart to be able to extend both x and y axis to negative values and be able to show the full data (hence no need to exclude the outliers).
Here is the code I have written:
p = figure(
x_axis_type = 'log',
y_axis_type = 'log',
height = 600,
sizing_mode = "stretch_width",
tools = TOOLS,
tooltips = TOOLTIPS,
toolbar_location = "above"
)
p.xaxis.major_label_orientation = 3.14 / 4
p.xaxis[0].formatter = NumeralTickFormatter(format="0")
p.yaxis[0].formatter = NumeralTickFormatter(format="0")
p.grid.grid_line_alpha = 0.3
low_x = fundamental['Profit [%]'].min()
high_x = fundamental['Profit [%]'].max()
low_y = fundamental['Profit Growth [%]'].min()
high_y = fundamental['Profit Growth [%]'].max()
p.line(x = (low_x, 0), y = (0, 0), color = 'red', line_width = 2, line_dash = 'dashed')
p.line(x = (0, 0), y = (low_y, 0), color = 'red', line_width = 2, line_dash = 'dashed')
p.line(x = (0, high_x), y = (0, 0), color = 'green', line_width = 2, line_dash = 'dashed')
p.line(x = (0, 0), y = (0, high_y), color = 'green', line_width = 2, line_dash = 'dashed')
show(p)
The data can be just random floats as long as it contains negative values. I'm using Python 3.8.13 and Bokeh 2.4.3 on a Windows 10 machine. Cheers!
Mathematically, the log
function is undefined ("infinite") at zero, and complex-valued for negative real numbers. So in the pure sense, a negative log axis is an impossibility. Some libraries (e.g. MPL I think) have implemented a symlog
("symmetric log") axis option that linearizes the scale in some interval around zero, and uses magnitudes for negative values, and stitches the ranges together so that things are "well defined". However, this approach is better suited for static plots that don't support panning and zooming. It would be a non-trivial amount of re-work to add it to Bokeh, and there has never been much demand for it, so no-one has ever decided to spend time on it.
Some other options:
DataTable
next to the plot.