Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Legend entry for text renderer causes error #7337

Closed
AlbertDude opened this issue Dec 19, 2017 · 6 comments · Fixed by #7360
Closed

Legend entry for text renderer causes error #7337

AlbertDude opened this issue Dec 19, 2017 · 6 comments · Fixed by #7360

Comments

@AlbertDude
Copy link

See: https://groups.google.com/a/continuum.io/forum/#!topic/bokeh/ZGhewELZos0

bokeh 0.12.13

I get the error:

"Uncaught TypeError: Cannot read property 'set_value' of undefined at e.n.TextView.e.draw_legend_for_index (bokeh-0.12.13.min.js:1)"

when I try to add a legend entry for text glyphs:

import bokeh.plotting as BPlotting
x = range(5)
y = x
t = [str(i) for i in y]
source = BPlotting.ColumnDataSource(data=dict(x=x, y=y, t=t))
p = BPlotting.figure()
p.circle('x', 'y', source=source, muted_alpha=0.2, legend='circle')
p.text('x', 'y', source=source, text='t', muted_alpha=0.2, legend='text')
p.line('x', 'y', source=source, muted_alpha=0.2, legend='line')
p.legend.location = "top_left"
p.legend.click_policy = "mute"
BPlotting.output_file('text.html')
BPlotting.show(p)

Uncaught TypeError: Cannot read property 'set_value' of undefined
at e.n.TextView.e.draw_legend_for_index (bokeh-0.12.13.min.js:sourcemap:1)
at e.n.GlyphRendererView.e.draw_legend (bokeh-0.12.13.min.js:sourcemap:1)
at e._draw_legend_items (bokeh-0.12.13.min.js:sourcemap:1)
at e.render (bokeh-0.12.13.min.js:sourcemap:1)
at e._paint_levels (bokeh-0.12.13.min.js:sourcemap:1)
at e.paint (bokeh-0.12.13.min.js:sourcemap:1)
at e._layout (bokeh-0.12.13.min.js:sourcemap:1)
at e.n.LayoutDOMView.e._layout (bokeh-0.12.13.min.js:sourcemap:1)
at e.n.LayoutDOMView.e._do_layout (bokeh-0.12.13.min.js:sourcemap:1)
at e.n.LayoutDOMView.e.layout (bokeh-0.12.13.min.js:sourcemap:1)

Screenshots or screencasts of the bug in action

image

@bryevdv
Copy link
Member

bryevdv commented Jan 2, 2018

@AlbertDude I will have a PR to fix the proximate problem, however, I still (and have never) considered text legends especially useful. With the PR it will look like this:

screen shot 2018-01-01 at 18 52 35

Basically it prints "text" with the matching color, plus the label you specify. I'm not actually sure what a text legend should do though, so if you have ideas please put them in a new feature request issue.

@bryevdv bryevdv added this to the 0.12.14 milestone Jan 2, 2018
@AlbertDude
Copy link
Author

Thanks Bryan,

A better sample use case for the text legend is below. Basically, I want a single legend entry to be attached to line, marker, and text elements so that all these elements can be muted/unmuted together.

Hopefully your fix is compatible with this usage.

Albert.

import bokeh.plotting as BPlotting
import bokeh.models as BModels

x  = range(5)
y  = x
t  = [str(i) for i in y]
y2 = [i*i for i in x]
t2 = [str(i) for i in y2]
source = BPlotting.ColumnDataSource(data=dict(x=x, y=y, t=t, y2=y2, t2=t2))

p = BPlotting.figure()
rend_c = p.circle('x', 'y', source=source, muted_alpha=0.2)
rend_t = p.text('x', 'y', source=source, text='t', muted_alpha=0.2)
rend_l = p.line('x', 'y', source=source, muted_alpha=0.2)

rend_c2 = p.circle('x', 'y2', source=source, muted_alpha=0.2)
rend_t2 = p.text('x', 'y2', source=source, text='t2', muted_alpha=0.2)
rend_l2 = p.line('x', 'y2', source=source, muted_alpha=0.2)

legend = BModels.Legend( items=[("Trace1", [rend_c, rend_l, rend_t]), ("Trace2", [rend_c2, rend_l2, rend_t2])] )
legend.click_policy="mute"
p.add_layout(legend, 'right')

BPlotting.output_file('text2.html')
BPlotting.save(p)

@bryevdv
Copy link
Member

bryevdv commented Jan 2, 2018

@AlbertDude It does work, clicking the legend entry hides all the glyphs including the text. However I would say the limited functionality of the text legend makes the visual appearance of the legend somewhat less than ideal:

screen shot 2018-01-02 at 12 20 11

I'd propose to merge this small PR as is, then make a follow on issue to support "linking" additional glyphs to be muted/hidden, that doesn't actually get draw in the legend. I think this would be most useful for things like LabelSet but I'm sure there are other applications. I thought there was alredy an issue for this, but I could not find one, can you make the issue?

As an aside, you might want to consider LabelSet instead of text for labeling points.

@bryevdv
Copy link
Member

bryevdv commented Jan 2, 2018

I suppose another quick option is to simply change text to not draw anything at all inside the legend box, on the assumption that this use case (being used together with other glyphs) is the primary reason it would ever be in a legend. That would be simple to do and would make the above look visually much better. Thoughts @bokeh/dev ?

@AlbertDude
Copy link
Author

Not drawing anything in the legend box for text elements would get my vote.

Thanks for the suggestion about LabelSet. I played around with it a bit -- it wasn't obvious to me as to how to add it to a legend entry so that it could be muted/unmuted. How would this be done?

@bryevdv
Copy link
Member

bryevdv commented Jan 2, 2018

it wasn't obvious to me as to how to add it to a legend entry so that it could be muted/unmuted. How would this be done?

It probably can't be currently, but I was thinking ahead to when there is some mechanism to link secondary glyphs to legend items.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants