Setting height for Bokeh Tabs - python-3.x

Is it possible to manually set a fixed height for every tabs of bokeh ? The code below generates two Tabs but in the HTML file, their height are based on the biggest one.
I would like to have a HTML file of two Tabs with a fixed height, and Tabs which exceed the fixed height would be managed by vertical scroll bar.
Thanks for help
from bokeh.models.widgets import Panel, Tabs
from bokeh.io import output_file, show
from bokeh.plotting import figure
output_file("slider.html")
p1 = figure(plot_width=300, plot_height=300)
p1.circle([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], size=20, color="navy", alpha=0.5)
tab1 = Panel(child=p1, title="circle")
p2 = figure(plot_width=300, plot_height=3000) # the biggest height, setting height for all tabs
p2.line([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], line_width=3, color="navy", alpha=0.5)
tab2 = Panel(child=p2, title="line")
tabs = Tabs(tabs=[ tab1, tab2 ], height=300) # this height is not considered in the HTML
show(tabs)

Related

changing the colour based on the graphs positions matplotlib

With the dataset below i am trying to plot a line graph on matplotlib. I am trying to make a function that looks at the previous number and checks whether the current number is higher. If the current function is bigger it would draw a blue line going to the next point such as it would draw a blue line between (1,100) and (2,9313). If its not greater (6,203542) and (7,203542), a red line would be drawn.
import matplotlib.pyplot as plt
x_long = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
L_Amount_list = [100.00, 9313.38, 43601.28, 61701.69, 74331.88, 198913.81, 153054.54, 119162.10, 74382.25, 203542.82, 160774.71, 220307.19, 366459.26]
plt.plot(x_long,L_Amount_list, color = 'green')
First, create a list of line colors for the graph with thresholds. Next, instead of drawing the graph one at a time, extract the data two at a time and set the list of colors.
import matplotlib.pyplot as plt
x_long = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
L_Amount_list = [100.00, 9313.38, 43601.28, 61701.69, 74331.88, 198913.81, 153054.54, 119162.10, 74382.25, 203542.82, 160774.71, 220307.19, 366459.26]
colors = ['b' if a < b else 'r' for a,b in zip(L_Amount_list,L_Amount_list[1:])]
for i in range(len(x_long)):
try:
plt.plot(x_long[i:i+2], L_Amount_list[i:i+2], color=colors[i])
except:
break
plt.show()

matplotlib graph shows up WITHOUT calling plt.show(), plt.show() doesn't display graph in separate cell in Jupyter Notebook

I got confused for the code I have here, when I develop my code into different cells in Jupyter Notebook, I gradually notice that the matplotlib graph shows up without calling plt.show(), which is anti-intuitive to me.
So if you implement the script below, the graph will pop up without plt.show():
data = np.array([
[5, 3, 2 ],
[2, -3, 5 ],
[ -4, 4, -6],
[-5, -3, -1],
[2, 6, 6]
])
bar_markers = np.array([4, 3, -2, 2, -1])
index = np.arange(len(data[:, 0]))
width = 0.15
fig, ax = plt.subplots()
ax.bar(index, data[:,0], width, bottom = 0, color = 'yellowgreen')
ax.bar(index+width, data[:, 1], width, bottom = 0, color = 'purple')
ax.bar(index+2*width, data[:, 2], width, bottom = 0, color = np.random.rand(3,))
ax.bar(index+width, [0]*len(bar_markers), width*3, bottom=bar_markers, edgecolor='k')
In a different word, this will cause confusion when you develop your code cell by cell in Jupyter Notebook, because 1)when you actually try to display graph using plt.show() in a different cell, it doesn't show any graph at all; 2) whenever you initialize graph using fig, ax = plt.subplots() it will display an empty graph right away. What I mean is shown below:
# in the first cell in Jupyter Notebook
data = np.array([
[5, 3, 2 ],
[2, -3, 5 ],
[ -4, 4, -6],
[-5, -3, -1],
[2, 6, 6]
])
bar_markers = np.array([4, 3, -2, 2, -1])
index = np.arange(len(data[:, 0]))
width = 0.15
fig, ax = plt.subplots()
Once implement it, the empty graph pops up without a reason.
# Then when you keep coding in a different cell
ax.bar(index, data[:,0], width, bottom = 0, color = 'yellowgreen')
ax.bar(index+width, data[:, 1], width, bottom = 0, color = 'purple')
ax.bar(index+2*width, data[:, 2], width, bottom = 0, color = np.random.rand(3,))
ax.bar(index+width, [0]*len(bar_markers), width*3, bottom=bar_markers, edgecolor='k')
plt.show()
It doesn't show anything at all.
If you know the reason why, please let us know, thank you in advance.

How do I get the x and y labels to appear when displaying more then one histogram using pandas hist() function with the by argument?

I am trying to create a series of graphs that share x and y labels. I can get the graphs to each have a label (explained well here!), but this is not what I am looking for.
I want one label that covers the y axis of both graphs, and same for the x axis.
I've been looking at the matplotlib and pandas documentation and I was unable to find anything that addresses this issues when the using by argument.
import matplotlib.pyplot as plt
import pandas as pd
df = pd.DataFrame({'A': [1, 2, 1, 2, 3, 4, 3, 4],
'B': [1, 7, 2, 4, 1, 4, 8, 3],
'C': [1, 4, 8, 3, 1, 7, 3, 4],
'D': [1, 2, 6, 5, 8, 3, 1, 7]},
index=[0, 1, 2, 3, 5, 6, 7, 8])
histo = df.hist(by=df['A'], sharey=True, sharex=True)
plt.ylabel('ylabel') # I assume the label is created on the 4th graph and then deleted?
plt.xlabel('xlabel') # Creates a label on the 4th graph.
plt.tight_layout()
plt.show()
The ouput looks like this.
Is there any way that I can create a Y Label that goes across the entire left side of the image (not each graph individually) and the same for the X Label.
As you can see, the x label only appears on the last graph created, and there is no y label.
Help?
This is one way to do it indirectly using the x- and y-labels as texts. I am not aware of a direct way using plt.xlabel or plt.ylabel. When passing an axis object to df.hist, the sharex and sharey arguments have to be passed in plt.subplots(). Here you can manually control/specify the position where you want to put the labels. For example, if you think the x-label is too close to the ticks, you can use 0.5, -0.02, 'X-label' to shift it slightly below.
import matplotlib.pyplot as plt
import pandas as pd
f, ax = plt.subplots(2, 2, figsize=(8, 6), sharex=True, sharey=True)
df = pd.DataFrame({'A': [1, 2, 1, 2, 3, 4, 3, 4],
'B': [1, 7, 2, 4, 1, 4, 8, 3],
'C': [1, 4, 8, 3, 1, 7, 3, 4],
'D': [1, 2, 6, 5, 8, 3, 1, 7]},
index=[0, 1, 2, 3, 5, 6, 7, 8])
histo = df.hist(by=df['A'], ax=ax)
f.text(0, 0.5, 'Y-label', ha='center', va='center', fontsize=20, rotation='vertical')
f.text(0.5, 0, 'X-label', ha='center', va='center', fontsize=20)
plt.tight_layout()
I fixed the issue with the variable number of sub-plots using something like this:
cols = 3
n = len(set(df['A']))
rows = int(n / cols) + (0 if n % cols == 0 else 1)
fig, axes = plt.subplots(rows, cols)
extra = rows * cols - n
if extra:
newaxes = []
count = 0
for row in range(rows):
for col in range(cols):
if count < n:
newaxes.append(axes[row][col])
else:
axes[row][col].axis('off')
count += 1
else:
newaxes = axes
hist = df.hist(by=df['A'], ax=newaxes)

Is there any way to plot lines of different lengths with bokeh?

Both down sampling and resizing are not feasible options for me, as suggested here.
I tried to pad the shorter lists with NaNs, but that threw up an error as well.
Is there any work around?
My code looks something like this:
from bokeh.charts import output_file, Line, save
lines=[[1,2,3],[1,2]]
output_file("example.html",title="toy code")
p = Line(lines,plot_width=600,plot_height=600, legend=False)
save(p)
However, as you see below you can plot two different lines with different lengths.
From Bokeh user guide on multiple lines:
from bokeh.plotting import figure, output_file, show
output_file("patch.html")
p = figure(plot_width=400, plot_height=400)
p.multi_line([[1, 3, 2], [3, 4, 6, 6]], [[2, 1, 4], [4, 7, 8, 5]],
color=["firebrick", "navy"], alpha=[0.8, 0.3], line_width=4)
show(p)

adding layout to tabs on bokeh dashboard

I'm exploring the bokeh library.
I tried to add several plots to each tab using VBox, but it did not work.
I read somewhere that tabs & VBox/HBox cannot be used together.
How do I handle the layout on the tabs then?
Modified example to add several elements per tab:
from bokeh.models.widgets import Panel, Tabs
from bokeh.io import output_file, show
from bokeh.plotting import figure
from bokeh.models.widgets.layouts import VBox
output_file("slider.html")
p1 = figure(plot_width=300, plot_height=300)
p1.circle([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], size=20, color="navy", alpha=0.5)
p2 = figure(plot_width=300, plot_height=300)
p2.line([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], line_width=3, color="navy", alpha=0.5)
p=VBox(p1,p2)
tab1 = Panel(child=p,title="circle")
tab2 = Panel(child=p2, title="line")
tabs = Tabs(tabs=[ tab1, tab2 ])
show(tabs)
Example from the website:
from bokeh.models.widgets import Panel, Tabs
from bokeh.io import output_file, show
from bokeh.plotting import figure
output_file("slider.html")
p1 = figure(plot_width=300, plot_height=300)
p1.circle([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], size=20, color="navy", alpha=0.5)
tab1 = Panel(child=p1, title="circle")
p2 = figure(plot_width=300, plot_height=300)
p2.line([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], line_width=3, color="navy", alpha=0.5)
tab2 = Panel(child=p2, title="line")
tabs = Tabs(tabs=[ tab1, tab2 ])
show(tabs)
I'm not sure about using HBox and VBox with Tabs, but you can use layout to arrange things in tabs, it has worked well for me and I think is a bit more flexible than the other options. Here's a quick example I think works:
from bokeh.layouts import layout
from bokeh.models.widgets import Tabs, Panel
from bokeh.io import curdoc
from bokeh.plotting import figure
fig1 = figure()
fig1.circle([0,1,2],[1,3,2])
fig2 = figure()
fig2.circle([0,0,2],[4,-1,1])
fig3 = figure()
fig3.circle([0,4,3],[1,2,0])
l1 = layout([[fig1, fig2]], sizing_mode='fixed')
l2 = layout([[fig3]],sizing_mode='fixed')
tab1 = Panel(child=l1,title="This is Tab 1")
tab2 = Panel(child=l2,title="This is Tab 2")
tabs = Tabs(tabs=[ tab1, tab2 ])
curdoc().add_root(tabs)
I found the movies example very useful for all sorts of stuff, the code for which is here, and well worth a look.

Resources