Reputation: 365
I am trying to draw a heatmap(spectrogram) in bokeh but when the heatmap displays it is empty..
This is the code which has some simply sample data, but this would be extended to fetch a large dataset via json.
from math import pi
import pandas as pd
from bokeh.io import show
from bokeh.models import LinearColorMapper, BasicTicker, PrintfTickFormatter, ColorBar
from bokeh.plotting import figure
# initialise data of lists.
data = {'epoch':[63745131000000, 63745131000000, 63745131100000,63745131100000], 'energy':[1.06811, 1.22078, 1.59495, 1.82245],'value':[3981.9308143034305, 2868.5202872178324, 1330.887696894385, 745.6847248644897]}
# Creates pandas DataFrame.
df = pd.DataFrame(data)
# print the data
print(df)
# this is the colormap from the original NYTimes plot
colors = ['#00007F', '#0000ff', '#007FFF', '#00ffff', '#7FFF7F', '#ffff00', '#FF7F00', '#ff0000', '#7F0000']
mapper = LinearColorMapper(palette=colors, low=df.value.min(), high=df.value.max())
TOOLS = "hover,save,pan,box_zoom,reset,wheel_zoom"
epochs = list(df.epoch.drop_duplicates())
print(epochs)
energies = list(df.energy.drop_duplicates())
print(energies)
p = figure(title="My Plot",
x_axis_location="below",
tools=TOOLS, toolbar_location='below',
tooltips=[('epoch', '@epoch'), ('energy', '@energy'), ('value', '@value')])
p.xaxis.ticker = epochs
p.yaxis.ticker = energies
p.grid.grid_line_color = None
p.axis.axis_line_color = None
p.axis.major_tick_line_color = None
p.axis.major_label_text_font_size = "5pt"
p.axis.major_label_standoff = 0
p.xaxis.major_label_orientation = pi / 3
p.rect(x="epoch", y="energy", width=1, height=1,
source=df,
fill_color={'field': 'value', 'transform': mapper},
line_color=None)
color_bar = ColorBar(color_mapper=mapper, major_label_text_font_size="5pt",
ticker=BasicTicker(desired_num_ticks=len(colors)),
label_standoff=6, border_line_color=None, location=(0, 0))
p.add_layout(color_bar, 'right')
show(p)
The frame which is output looks correct:
epoch energy value
0 63745131000000 1.06811 3981.930814
1 63745131000000 1.22078 2868.520287
2 63745131100000 1.59495 1330.887697
3 63745131100000 1.82245 745.684725
and the ranges for the x and y look ok as well:
[63745131000000, 63745131100000]
[1.06811, 1.22078, 1.59495, 1.82245]
But the image that appears has no points plotted:
I should mention, if I simply change the second epoch to one after e.g)
'epoch':[63745131000000, 63745131000000, 63745131000001,63745131000001]
Then the chart seems to be displayed correctly:
Grateful for any help. Thanks
Upvotes: 0
Views: 379
Reputation: 1629
The reason why there is no information showing up is because at the edge bokeh apparently does not think your part of the data is something that deserves a color.
What you should change is the limits in you mapper:
mapper = LinearColorMapper(palette=colors, low=df.value.min()-1, high=df.value.max()+1) # this will make sure your data is inside the mapping
Also your width is defined in the figure a being 1. When your epochs are differing with a million you will still see almost nothing when you are plotting this so change
p.rect(x="epoch", y="energy", width=100000, height=1, # here width is set to an adequate level.
source=df,
fill_color={'field': 'value', 'transform': mapper},
line_color=None)
Upvotes: 2