Skip to content

Commit

Permalink
Fix layout titles (#3041)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahuang11 authored and philippjfr committed Oct 25, 2018
1 parent 2349efa commit 55e988a
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 17 deletions.
47 changes: 36 additions & 11 deletions holoviews/plotting/bokeh/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

from bokeh.layouts import gridplot
from bokeh.plotting.helpers import _known_tools as known_tools
from holoviews.plotting.bokeh.util import theme_attr_json

TOOLS = {name: tool if isinstance(tool, basestring) else type(tool())
for name, tool in known_tools.items()}
Expand Down Expand Up @@ -340,28 +341,52 @@ class CompositePlot(BokehPlot):
to such a plot.
"""

fontsize = param.Parameter(default={'title': '16pt'}, allow_None=True, doc="""
fontsize = param.Parameter(default={'title': '15pt'}, allow_None=True, doc="""
Specifies various fontsizes of the displayed text.
Finer control is available by supplying a dictionary where any
unmentioned keys reverts to the default sizes, e.g:
{'title': '15pt'}""")

_title_template = "<span style='font-size: {fontsize}'><b>{title}</b></font>"
_title_template = (
'<span style='
'"color:{color};font-family:{font};'
'font-style:{fontstyle};font-weight:{fontstyle};' # italic/bold
'font-size:{fontsize}">'
'{title}</span>'
)

def _get_title(self, key):
title_div = None
title = self._format_title(key) if self.show_title else ''
if title:
fontsize = self._fontsize('title')
title_tags = self._title_template.format(title=title,
**fontsize)
if 'title' in self.handles:
title_div = self.handles['title']
else:
title_div = Div()
title_div.text = title_tags
if not title:
return title_div

title_json = theme_attr_json(self.renderer.theme, 'Title')
color = title_json.get('text_color', None)
font = title_json.get('text_font', 'Arial')
fontstyle = title_json.get('text_font_style', 'bold')
fontsize = self._fontsize('title')['fontsize']
if fontsize == '15pt': # if default
fontsize = title_json.get('text_font_size', '15pt')
if 'em' in fontsize:
# it's smaller than it shosuld be so add 0.25
fontsize = str(float(fontsize[:-2]) + 0.25) + 'em'

title_tags = self._title_template.format(
color=color,
font=font,
fontstyle=fontstyle,
fontsize=fontsize,
title=title)

if 'title' in self.handles:
title_div = self.handles['title']
else:
title_div = Div(width=450) # so it won't wrap long titles easily
title_div.text = title_tags

return title_div

@property
Expand Down
14 changes: 14 additions & 0 deletions holoviews/plotting/bokeh/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
from bokeh.models import Model, ToolbarBox, FactorRange, Range1d, Plot, Spacer, CustomJS
from bokeh.models.widgets import DataTable, Tabs, Div
from bokeh.plotting import Figure
from bokeh.themes.theme import Theme
if bokeh_version <= '0.13.0':
built_in_themes = {}
else:
from bokeh.themes import built_in_themes

try:
from bkcharts import Chart
Expand Down Expand Up @@ -660,3 +665,12 @@ def colormesh(X, Y):
X = np.column_stack([X1, X2, X3, X4, X1])
Y = np.column_stack([Y1, Y2, Y3, Y4, Y1])
return X, Y


def theme_attr_json(theme, attr):
if isinstance(theme, str) and theme in built_in_themes:
return built_in_themes[theme]._json['attrs'].get(attr, {})
elif isinstance(theme, Theme):
return theme._json['attrs'].get(attr, {})
else:
return {}
6 changes: 4 additions & 2 deletions holoviews/tests/plotting/bokeh/testgridplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ def test_grid_title(self):
plot = bokeh_renderer.get_plot(grid)
title = plot.handles['title']
self.assertIsInstance(title, Div)
text = "<span style='font-size: 16pt'><b>X: 0</b></font>"
text = ('<span style="color:black;font-family:Arial;'
'font-style:bold;font-weight:bold;font-size:16pt">X: 0</span>')
self.assertEqual(title.text, text)

def test_grid_title_update(self):
Expand All @@ -34,7 +35,8 @@ def test_grid_title_update(self):
plot.update(1)
title = plot.handles['title']
self.assertIsInstance(title, Div)
text = "<span style='font-size: 16pt'><b>X: 1</b></font>"
text = ('<span style="color:black;font-family:Arial;'
'font-style:bold;font-weight:bold;font-size:16pt">X: 1</span>')
self.assertEqual(title.text, text)

def test_gridmatrix_overlaid_batched(self):
Expand Down
11 changes: 7 additions & 4 deletions holoviews/tests/plotting/bokeh/testlayoutplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ def test_layout_title(self):
plot = bokeh_renderer.get_plot(hmap1+hmap2)
title = plot.handles['title']
self.assertIsInstance(title, Div)
text = "<span style='font-size: 16pt'><b>Default: 0</b></font>"
text = ('<span style="color:black;font-family:Arial;font-style:bold;'
'font-weight:bold;font-size:12pt">Default: 0</span>')
self.assertEqual(title.text, text)

def test_layout_title_fontsize(self):
Expand All @@ -44,7 +45,8 @@ def test_layout_title_fontsize(self):
plot = bokeh_renderer.get_plot(layout)
title = plot.handles['title']
self.assertIsInstance(title, Div)
text = "<span style='font-size: 12pt'><b>Default: 0</b></font>"
text = ('<span style="color:black;font-family:Arial;font-style:bold;'
'font-weight:bold;font-size:12pt">Default: 0</span>')
self.assertEqual(title.text, text)

def test_layout_title_show_title_false(self):
Expand All @@ -61,7 +63,8 @@ def test_layout_title_update(self):
plot.update(1)
title = plot.handles['title']
self.assertIsInstance(title, Div)
text = "<span style='font-size: 16pt'><b>Default: 1</b></font>"
text = ('<span style="color:black;font-family:Arial;font-style:bold;'
'font-weight:bold;font-size:12pt">Default: 1</span>')
self.assertEqual(title.text, text)

def test_layout_gridspaces(self):
Expand Down Expand Up @@ -164,7 +167,7 @@ def test_layout_plot_tabs_with_adjoints(self):
self.assertIsInstance(panel2, Panel)
self.assertEqual(panel1.title, 'Curve I')
self.assertEqual(panel2.title, 'AdjointLayout I')

def test_layout_shared_source_synced_update(self):
hmap = HoloMap({i: Dataset({chr(65+j): np.random.rand(i+2)
for j in range(4)}, kdims=['A', 'B', 'C', 'D'])
Expand Down

0 comments on commit 55e988a

Please sign in to comment.