How to get a figure from a chart?

I’ve spent a bunch of time poking around the documentation for this, and I still don’t see the answer, so I thought I’d ask the group.

The bokeh high level charts interface http://bokeh.pydata.org/en/latest/docs/reference/charts.html
returns objects of type bokeh.charts.Chart

However, most of the documentation and samples works on figures (bokeh.plotting.figure.Figure)
How do I get the figure from a chart?

In particular, I’d like to add some annotations such as Spans
http://bokeh.pydata.org/en/0.11.1/docs/user_guide/plotting.html#spans
or text labels

I’ve tried just calling add_glyph() on the chart and the text labels don’t seem to show up.

Shankari

Hi Shankari,

There's no way to make a Figure out of Chart, but all the parent class methods (e.g. Plot.add_glyph) should work. Can you share some code to show exactly what you've tried?

FYI, many of the convenience methods for accessing grids and axes, as well as all the "glyph methods" like circle, text, etc. will be available directly on Chart in the upcoming 0.12 release.

Thanks,

Bryan

···

On May 12, 2016, at 2:58 AM, [email protected] wrote:

I've spent a bunch of time poking around the documentation for this, and I still don't see the answer, so I thought I'd ask the group.

The bokeh high level charts interface http://bokeh.pydata.org/en/latest/docs/reference/charts.html
returns objects of type bokeh.charts.Chart

However, most of the documentation and samples works on figures (bokeh.plotting.figure.Figure)
How do I get the figure from a chart?

In particular, I'd like to add some annotations such as Spans
Bokeh Docs
or text labels
glyphs — Bokeh 3.3.2 Documentation

I've tried just calling add_glyph() on the chart and the text labels don't seem to show up.

Shankari

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/abe191f4-cb22-49b2-8b5d-dc75c620c1b9%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

It seems to me that it would be easier for the user if the charts api just returned a Figure object - having a different and incompatible api seems to just make it harder to use.

A couple of concrete questions

  • How can I plot a chart on an existing Figure

  • It seems to conflate figure creation with plotting - e.g. figure kwargs plot_height etc are now passed to the chart creation function

  • How can I set the x/y axis labels when the Chart doesn’t have an xaxis or yaxis?

  • How can I get a reference to the legend?

Thanks,

Dave

···

On Thursday, 12 May 2016 18:50:27 UTC+10, Bryan Van de ven wrote:

Hi Shankari,

There’s no way to make a Figure out of Chart, but all the parent class methods (e.g. Plot.add_glyph) should work. Can you share some code to show exactly what you’ve tried?

FYI, many of the convenience methods for accessing grids and axes, as well as all the “glyph methods” like circle, text, etc. will be available directly on Chart in the upcoming 0.12 release.

Thanks,

Bryan

On May 12, 2016, at 2:58 AM, shan…@berkeley.edu wrote:

I’ve spent a bunch of time poking around the documentation for this, and I still don’t see the answer, so I thought I’d ask the group.

The bokeh high level charts interface http://bokeh.pydata.org/en/latest/docs/reference/charts.html

returns objects of type bokeh.charts.Chart

However, most of the documentation and samples works on figures (bokeh.plotting.figure.Figure)

How do I get the figure from a chart?

In particular, I’d like to add some annotations such as Spans

http://bokeh.pydata.org/en/0.11.1/docs/user_guide/plotting.html#spans

or text labels

http://bokeh.pydata.org/en/latest/docs/reference/models/glyphs.html#bokeh.models.glyphs.Text

I’ve tried just calling add_glyph() on the chart and the text labels don’t seem to show up.

Shankari

It seems to me that it would be easier for the user if the charts api just returned a Figure object - having a different and incompatible api seems to just make it harder to use.

The Charts API returns a Plot object (subclass) That is the common class type you are looking for. bokeh.plotting and bokeh.charts are different APIs. Figure has different assumptions, so it's not workable to have Chart inherit from Figure. That said, some of the convenience functionality that was previously only on Figure, has been moved down to Plot, so that they will now also be available on charts. I hope this will satisfy your needs.

A couple of concrete questions
* How can I plot a chart on an existing Figure

You can't. Charts are not yet composable in this way. In 0.12 you will be able to use glyph methods like .line, .circle, etc. directly on Charts. This is not quite the same, but hopefully opens up enough capability to satisfy most use cases.

* It seems to conflate figure creation with plotting - e.g. figure kwargs `plot_height` etc are now passed to the chart creation function

I don't understand this, to be honest. Charts, like any Plot, have a canvas size, and this is just how you can specify it in a consistent way across APIs.

* How can I set the x/y axis labels when the Chart doesn't have an xaxis or yaxis?

for now, use .select, in 0.12 Charts will have .xaxis and .yaxis

* How can I get a reference to the legend?

same, for now use .select, in 0.12 Charts will have .legend

Thanks,

Bryan

···

On May 17, 2016, at 4:44 AM, [email protected] wrote:

Can you share some code to show exactly what you’ve tried?

Unfortunately, it is at the tail end of a bunch of other processing, and I deleted my “TestBokeh” ipython notebook. I’ll see if I can recreate it, or whether I managed to commit it somewhere and share it with you. For now, I’ve decided to just fall back to standard figures - they are not that hard to use.

FYI, many of the convenience methods for accessing grids and axes, as well as all the “glyph methods” like circle, text, etc. will be available directly on Chart in the upcoming 0.12 release.

That’s basically what I’m looking for. Any ideas on when 0.12 will be out? :slight_smile:
Shankari

Can you share some code to show exactly what you’ve tried?

Unfortunately, it is at the tail end of a bunch of other processing, and I deleted my “TestBokeh” ipython notebook. I’ll see if I can recreate it, or whether I managed to commit it somewhere and share it with you. For now, I’ve decided to just fall back to standard figures - they are not that hard to use.

FYI, many of the convenience methods for accessing grids and axes, as well as all the “glyph methods” like circle, text, etc. will be available directly on Chart in the upcoming 0.12 release.

That’s basically what I’m looking for. Any ideas on when 0.12 will be out? :slight_smile:
Shankari

Indeed, the Charts in 0.12 sound like they’re a lot more usable - looking forward to the release!

I don’t understand this, to be honest. Charts, like any Plot, have a canvas size, and this is just how you can specify it in a consistent way across APIs.

I think there’s some confusion in the terminology. In the matplotlib world which I’m familiar with the Figure is a container of different plots which may be line, bar, scatter etc.

In bokeh it seems Figure and Plot are use synonymously with a (matplotlib-style) plot being just a collection of gylphs represented by a GylphRenderer?

Terminology aside, the api seems similar between the two - in matplotlib parlance you create a Figure passing in arguments which only make sense for the container of plots (such as figsize). After creating the figure you then add plots to it, be they lines, scatter plots or images. In bokeh you create a Plot (using the plt.figure function) passing in plot_height, plot_width. You then add plots (collections of Gylphs) using the Plot.line etc functions which don’t themselves take the Plot creation kwargs.

A Chart behaves differently, it both creates the Plot and adds the gylphs / GylphRenders to it so the Plot creation kwargs are commingled with the gylph-styling kwargs. This combining of responsibilities makes it less flexible in that you can’t add Charts to an existing Plot.

Returning a new Chart object also doesn’t seem to add much benefit to me - AFAICT it must just be a Plot with a bunch of gylph / GylphRenderers and as such you could immediately manipulate it in the same way as any other Plot as described in the documentation and SO examples. If you return a new object with a different api it just makes bokeh that much harder to learn and to use. Also, from a maintenance point of view it would seem you have to reimplement every functionality already existing on the Plot object hence doubling the burden. I’m honestly curious what benefit a Chart object brings over just returning the underlying Plot?

I don’t want to come across as overly critical, I think bokeh is an amazing library and my observations are just intended to be useful feedback. If I do sometimes find it difficult to grok the bokeh way that’s just as likely to be my ingrained matplotlib habit which new users might not suffer from.

Thanks,

Dave

Thanks,

Dave

···

On Wednesday, 18 May 2016 07:25:58 UTC+10, shan…@berkeley.edu wrote:

Hi Dave,

I guess one thing I've tried to convey but have not done an adequate job of is that at the bottom, *everything* is just a collection of Models from the bokeh.models "API". That means everything from bokeh.plotting or bokeh.charts is really just a collection of bokeh.models things. This is really because ultimately everything has to be serialized in a consistent way to BokehJS. As you note, as a consequence all things can be modified and manipulated in the same way, by modifying model properties. I take this as a good and simplifying feature. Now it's also possible to create anything you want by building up low level models "by hand", which is powerful but can be tedious. All of this taken together I hope it points to the most important reason for the other APIs: to encapsulate common patterns of plot creation in convenient ways:

* bokeh.plotting -- make a basic default plot, easy to add (vectorized) visual shapes, with attributed tied very directly to data

* bokeh.charts -- encapsulate common high-level statistical charts, possibly *processing or manipulating the source data* to get the data needed for low level models

Figure and Chart are ultimately kinds of Plot, which is why they inherit from Plot and accept "Plot" attributes. But they also have their own distinct features and assumptions which is why they do not inherit from one another. As a concrete example, Figure exposes things like x_range because it is easy and useful to give an explicit range to this kind of simple plot. But Charts are more complicated and may need to compute a range automatically, based on a groupby or some other statistical process on the data. It can't expose x_range, otherwise people would try to use it, with undesirable results (and the spurious bug reports) that entails.

Yes, AFAIK these terms are not used identically to MPL, but also AFAIK "Figure" does not have a specific technical meaning. For us, it was just a convenient and reasonably meaningful name available to use for this other level of plot construction.

Hope some of that is useful,

Bryan

···

On May 17, 2016, at 10:22 PM, [email protected] wrote:

On Wednesday, 18 May 2016 07:25:58 UTC+10, shan...@berkeley.edu wrote:
> Can you share some code to show exactly what you've tried?
Unfortunately, it is at the tail end of a bunch of other processing, and I deleted my "TestBokeh" ipython notebook. I'll see if I can recreate it, or whether I managed to commit it somewhere and share it with you. For now, I've decided to just fall back to standard figures - they are not that hard to use.

> FYI, many of the convenience methods for accessing grids and axes, as well as all the "glyph methods" like circle, text, etc. will be available directly on Chart in the upcoming 0.12 release.

That's basically what I'm looking for. Any ideas on when 0.12 will be out? :slight_smile:
Shankari

Indeed, the Charts in 0.12 sound like they're a lot more usable - looking forward to the release!

> I don't understand this, to be honest. Charts, like any Plot, have a canvas size, and this is just how you can specify it in a consistent way across APIs.

I think there's some confusion in the terminology. In the matplotlib world which I'm familiar with the Figure is a container of different plots which may be line, bar, scatter etc.

In bokeh it seems Figure and Plot are use synonymously with a (matplotlib-style) plot being just a collection of gylphs represented by a GylphRenderer?

Terminology aside, the api seems similar between the two - in matplotlib parlance you create a Figure passing in arguments which only make sense for the container of plots (such as figsize). After creating the figure you then add plots to it, be they lines, scatter plots or images. In bokeh you create a Plot (using the plt.figure function) passing in plot_height, plot_width. You then add plots (collections of Gylphs) using the `Plot.line` etc functions which don't themselves take the Plot creation kwargs.

A Chart behaves differently, it both creates the Plot and adds the gylphs / GylphRenders to it so the Plot creation kwargs are commingled with the gylph-styling kwargs. This combining of responsibilities makes it less flexible in that you can't add Charts to an existing Plot.

Returning a new `Chart` object also doesn't seem to add much benefit to me - AFAICT it must just be a Plot with a bunch of gylph / GylphRenderers and as such you could immediately manipulate it in the same way as any other Plot as described in the documentation and SO examples. If you return a new object with a different api it just makes bokeh that much harder to learn and to use. Also, from a maintenance point of view it would seem you have to reimplement every functionality already existing on the Plot object hence doubling the burden. I'm honestly curious what benefit a Chart object brings over just returning the underlying Plot?

I don't want to come across as overly critical, I think bokeh is an amazing library and my observations are just intended to be useful feedback. If I do sometimes find it difficult to grok the bokeh way that's just as likely to be my ingrained matplotlib habit which new users might not suffer from.

Thanks,
Dave

Thanks,
Dave

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/55ba2b11-a648-42be-8c3a-9c94aebc331d%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

That is very useful so thanks for taking the time to give a bit more background on the design of bokeh!

Cheers,

Dave

···

On Fri, May 20, 2016 at 12:38 AM, Bryan Van de Ven [email protected] wrote:

Hi Dave,

I guess one thing I’ve tried to convey but have not done an adequate job of is that at the bottom, everything is just a collection of Models from the bokeh.models “API”. That means everything from bokeh.plotting or bokeh.charts is really just a collection of bokeh.models things. This is really because ultimately everything has to be serialized in a consistent way to BokehJS. As you note, as a consequence all things can be modified and manipulated in the same way, by modifying model properties. I take this as a good and simplifying feature. Now it’s also possible to create anything you want by building up low level models “by hand”, which is powerful but can be tedious. All of this taken together I hope it points to the most important reason for the other APIs: to encapsulate common patterns of plot creation in convenient ways:

  • bokeh.plotting – make a basic default plot, easy to add (vectorized) visual shapes, with attributed tied very directly to data

  • bokeh.charts – encapsulate common high-level statistical charts, possibly processing or manipulating the source data to get the data needed for low level models

Figure and Chart are ultimately kinds of Plot, which is why they inherit from Plot and accept “Plot” attributes. But they also have their own distinct features and assumptions which is why they do not inherit from one another. As a concrete example, Figure exposes things like x_range because it is easy and useful to give an explicit range to this kind of simple plot. But Charts are more complicated and may need to compute a range automatically, based on a groupby or some other statistical process on the data. It can’t expose x_range, otherwise people would try to use it, with undesirable results (and the spurious bug reports) that entails.

Yes, AFAIK these terms are not used identically to MPL, but also AFAIK “Figure” does not have a specific technical meaning. For us, it was just a convenient and reasonably meaningful name available to use for this other level of plot construction.

Hope some of that is useful,

Bryan

On May 17, 2016, at 10:22 PM, [email protected] wrote:

On Wednesday, 18 May 2016 07:25:58 UTC+10, shan…@berkeley.edu wrote:

Can you share some code to show exactly what you’ve tried?

Unfortunately, it is at the tail end of a bunch of other processing, and I deleted my “TestBokeh” ipython notebook. I’ll see if I can recreate it, or whether I managed to commit it somewhere and share it with you. For now, I’ve decided to just fall back to standard figures - they are not that hard to use.

FYI, many of the convenience methods for accessing grids and axes, as well as all the “glyph methods” like circle, text, etc. will be available directly on Chart in the upcoming 0.12 release.

That’s basically what I’m looking for. Any ideas on when 0.12 will be out? :slight_smile:

Shankari

Indeed, the Charts in 0.12 sound like they’re a lot more usable - looking forward to the release!

I don’t understand this, to be honest. Charts, like any Plot, have a canvas size, and this is just how you can specify it in a consistent way across APIs.

I think there’s some confusion in the terminology. In the matplotlib world which I’m familiar with the Figure is a container of different plots which may be line, bar, scatter etc.

In bokeh it seems Figure and Plot are use synonymously with a (matplotlib-style) plot being just a collection of gylphs represented by a GylphRenderer?

Terminology aside, the api seems similar between the two - in matplotlib parlance you create a Figure passing in arguments which only make sense for the container of plots (such as figsize). After creating the figure you then add plots to it, be they lines, scatter plots or images. In bokeh you create a Plot (using the plt.figure function) passing in plot_height, plot_width. You then add plots (collections of Gylphs) using the Plot.line etc functions which don’t themselves take the Plot creation kwargs.

A Chart behaves differently, it both creates the Plot and adds the gylphs / GylphRenders to it so the Plot creation kwargs are commingled with the gylph-styling kwargs. This combining of responsibilities makes it less flexible in that you can’t add Charts to an existing Plot.

Returning a new Chart object also doesn’t seem to add much benefit to me - AFAICT it must just be a Plot with a bunch of gylph / GylphRenderers and as such you could immediately manipulate it in the same way as any other Plot as described in the documentation and SO examples. If you return a new object with a different api it just makes bokeh that much harder to learn and to use. Also, from a maintenance point of view it would seem you have to reimplement every functionality already existing on the Plot object hence doubling the burden. I’m honestly curious what benefit a Chart object brings over just returning the underlying Plot?

I don’t want to come across as overly critical, I think bokeh is an amazing library and my observations are just intended to be useful feedback. If I do sometimes find it difficult to grok the bokeh way that’s just as likely to be my ingrained matplotlib habit which new users might not suffer from.

Thanks,

Dave

Thanks,

Dave

You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/55ba2b11-a648-42be-8c3a-9c94aebc331d%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

You received this message because you are subscribed to a topic in the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this topic, visit https://groups.google.com/a/continuum.io/d/topic/bokeh/DJJWAyOTv0A/unsubscribe.

To unsubscribe from this group and all its topics, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/6B582F11-4E9F-457D-B350-760469A81CED%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.