Display hours,minutes,seconds,msecs on xaxis in bokeh plot - python

I want to display xaxis in below format. It should include hr,min,secs,msecs format
14:38:21:701, 14:38:21:702..
Below is the code I have written
#!/usr/bin/python3
from bokeh.plotting import figure, output_file, show
import pandas as pd
from bokeh.models import DatetimeTickFormatter, ColumnDataSource, PrintfTickFormatter
from pandas import ExcelWriter, ExcelFile
weight = pd.read_excel('file_name.xlsx')
source = ColumnDataSource(weight)
#Take data and present in a graph
output_file("test.html")
p = figure(plot_width=1500, plot_height=400)
p.left[0].formatter.use_scientific = False
p.xaxis[0].formatter.use_scientific = False
#Need to modify this format to display hours,minutes,seconds,msecs
p.xaxis[0].formatter = PrintfTickFormatter(format="%sms")
p.scatter(x='Time',y='Bearer ID 5 WM Low', color = "navy",source=source,legend_label='Bearer ID 5 WM Low')
p.scatter(x='Time',y='Bearer ID 5 VM Count', color = "red",source=source,legend_label='Bearer ID 5 VM Count')
show(p)
Below is the output for it.

You could use DatetimeFormatter instead of PrintfTickFormatter.
Visit DatetimeTickFormatter for the documentation

Related

How to plot LabelSet outside the plot box?

I'm trying to highlight last value of a time series plot by plot its value on yaxis, as shown in this question. I prefer using LabelSet over Legend because you can precisely control the text positions and also using a data source to update it. But unfortunately, I can not find out how to draw label text outside the plot box.
Here is some code to plot LabelSet and notice how the text is only shown inside the box (66.1x is partially blocked by yaxis):
import pandas as pd
from bokeh.io import output_notebook
output_notebook()
from bokeh.plotting import figure, show
from bokeh.models import LabelSet, ColumnDataSource
#import bokeh.sampledata
#bokeh.sampledata.download()
from bokeh.sampledata.stocks import MSFT
df = pd.DataFrame(MSFT)[:50]
df["date"] = pd.to_datetime(df["date"])
p = figure(
x_axis_type="datetime", width=1000, toolbar_location='left',
title = "MSFT Candlestick", y_axis_location="right")
p.line(df.date, df.close)
ds = ColumnDataSource({'x': [df.date.iloc[-1]], 'y': [df.close.iloc[-1]], 'text': [' ' + str(df.close.iloc[-1])]})
ls = LabelSet(x='x', y='y', text='text', source=ds)
p.add_layout(ls)
show(p)
Please let me know how to show LabelSet outside the box, Thanks

Adding single python bokeh label

I am trying to add a single label at a specific spot on a bokeh chart. I know this easy but I can't seem to find the code that works for me.
I am trying to use the Label in bokeh.models but it isn't working.
I know the exact x and y coordinates, text and text color but it isn't working.
Any help will be greatly appreciated.
from bokeh.plotting import figure, output_file, show
from bokeh.io import output_notebook
from bokeh.models.tools import HoverTool
from bokeh.models import Label
output_notebook()
graph = figure(title = "Average Yearly Temperature per US State",)
for state in us_state_temps.columns:
if state == 'California':
graph.line(us_state_temps.index, us_state_temps[state], line_width = 2, color = "red")
else:
graph.line(us_state_temps.index, us_state_temps[state], line_width = 0.5, color = 'gray')
graph.xaxis.axis_label = 'Year'
graph.yaxis.axis_label = "Average Yearly Temperature °C"
graph.toolbar_location = None
graph.toolbar.active_drag = None
california = Label(x=70, y=1960, x_units='screen', y_units='screen', text='California')
graph.add_layout(california)
hover = HoverTool()
hover.tooltips = [('Year', '#x'), ('Average temp.', '#y')]
graph.add_tools(hover)
show(graph)

Labels not appearing in python bokeh bar plot with groups

I want to add labels with the values above the bars like here: How to add data labels to a bar chart in Bokeh? but don't know how to do it. My code looks different then other examples, the code is working but maybe it is not the right way.
My code:
from bokeh.io import export_png
from bokeh.io import output_file, show
from bokeh.palettes import Spectral5
from bokeh.plotting import figure
from bokeh.sampledata.autompg import autompg_clean as df
from bokeh.transform import factor_cmap
from bokeh.models import ColumnDataSource, ranges, LabelSet, Label
import pandas as pd
d = {'lvl': ["lvl1", "lvl2", "lvl2", "lvl3"],
'feature': ["test1", "test2","test3","test4"],
'count': ["5", "20","8", "90"]}
dfn = pd.DataFrame(data=d)
sourceframe = ColumnDataSource(data=dfn)
groupn = dfn.groupby(by=['lvl', 'feature'])
index_cmapn = factor_cmap('lvl_feature', palette=Spectral5, factors=sorted(dfn.lvl.unique()), end=1)
pn = figure(plot_width=800, plot_height=300, title="Count",x_range=groupn, toolbar_location=None)
labels = LabelSet(x='feature', y='count', text='count', level='glyph',x_offset=0, y_offset=5, source=sourceframe, render_mode='canvas',)
pn.vbar(x='lvl_feature', top="count_top" ,width=1, source=groupn,line_color="white", fill_color=index_cmapn, )
pn.y_range.start = 0
pn.x_range.range_padding = 0.05
pn.xgrid.grid_line_color = None
pn.xaxis.axis_label = "levels"
pn.xaxis.major_label_orientation = 1.2
pn.outline_line_color = None
pn.add_layout(labels)
export_png(pn, filename="color.png")
I think it has something to do with my dfn.groupby(by=['lvl', 'feature']) and the (probably wrong) sourceframe = ColumnDataSource(data=dfn).
The plot at this moment:
You can add the groups names in the initial dictionary like this:
d = {'lvl': ["lvl1", "lvl2", "lvl2", "lvl3"],
'feature': ["test1", "test2","test3","test4"],
'count': ["5", "20","8", "90"],
'groups': [('lvl1', 'test1'), ('lvl2', 'test2'), ('lvl2', 'test3'), ('lvl3', 'test4')]}
And then call LabelSet using as x values the groups.
labels = LabelSet(x='groups', y='count', text='count', level='glyph',x_offset=20, y_offset=0, source=sourceframe, render_mode='canvas',)
In this way the labels appear. Note that I played a bit with the offset to check if that was the problem, you can fix that manually.

How to expand limited color palette in Python's Bokeh plot

I have the following code:
from bokeh.plotting import figure, show, output_file
from bokeh.sampledata.iris import flowers
from bokeh.models import LinearColorMapper
from bokeh.models import ColumnDataSource
from bokeh.models import ColorBar
from bokeh.palettes import Reds9
p = figure(title = "Iris Morphology")
p.xaxis.axis_label = "Petal Length"
p.yaxis.axis_label = "Petal Width"
source = ColumnDataSource(flowers)
# Reverse the color and map it
Reds9.reverse()
exp_cmap = LinearColorMapper(palette=Reds9,
low = min(flowers["petal_length"]),
high = max(flowers["petal_length"]))
p.circle("petal_length", "petal_width", source=source, line_color=None,
fill_color={"field":"petal_length", "transform":exp_cmap})
bar = ColorBar(color_mapper=exp_cmap, location=(0,0))
p.add_layout(bar, "left")
show(p)
Which produces the following plot:
Notice that I use Brewer's Red palette which is limited to 9 colors.
from bokeh.palettes import Reds9
How can I expand it to 256?
Bokeh's palettes are simply a list of HTML colors. You can create your own one. For example, picking the list from https://www.w3schools.com/colors/colors_shades.asp:
myReds = [
'#000000',
'#080000',
'#100000',
'#180000',
'#200000',
'#280000',
'#300000',
'#380000',
'#400000',
'#480000',
'#500000',
'#580000',
'#600000',
'#680000',
'#700000',
'#780000',
'#800000',
'#880000',
'#900000',
'#980000',
'#A00000',
'#A80000',
'#B00000',
'#B80000',
'#C00000',
'#C80000',
'#D00000',
'#D80000',
'#E00000',
'#E80000',
'#F00000',
'#F80000',
'#FF0000']
Then replace Reds9 by myReds:
[...]
exp_cmap = LinearColorMapper(palette=myReds,
low = min(flowers["petal_length"]),
high = max(flowers["petal_length"]))
[...]

Python bokeh set line color based on dataframe column

In bokeh line chart, is there a way to set the color of the line based on a dataframe column? I am trying the following but it doesn't work. The chart doesn't show up if i use the color argument as shown below. If I remove that it shows up.
import pandas as pd
from bokeh.io import show
from bokeh.plotting import figure
from bokeh.models import NumeralTickFormatter, HoverTool
data = pd.read_csv('C:\\Users\\asde\\Desktop\\Python\\bok\\StateNames.csv',thousands=',',index_col='Id')
#data1 = data[(data.Name == 'Mary')& (data.State == 'AZ')]
data.apply(lambda x: pd.to_numeric(x, errors='ignore'))
data2 = data[(data.Year >= 2010) & (data.Year <= 2014)& (data.State == 'AZ')]
data2.head()
p = figure()
#p.line(x=data1['Year'],y=data1['Count'])
p.line(x=data2['Year'],y=data2['Count'],***color = data2['Name']***)
p.xaxis[0].formatter = NumeralTickFormatter(format='0000')
show(p)

Categories

Resources