## Where communities thrive

• Join over 1.5M+ people
• Join over 100K+ communities
• Free without limits
##### Activity
• Apr 21 15:18
• Apr 21 04:08
gavinhodge commented #199
• Apr 21 04:08
gavinhodge opened #199
• Feb 03 16:51
• Feb 02 16:38
janxkoci commented #52
• Jun 01 2020 07:56
kmatt closed #75
• May 25 2020 22:22
• May 25 2020 12:42
pulkin opened #198
• May 18 2020 21:42

Create a notebook with some exa… (compare)

• May 01 2020 19:04

More work on the !@\$! mp4 and p… (compare)

• May 01 2020 18:52

• May 01 2020 18:21

Regenerate conf.py from scratch… (compare)

• Apr 28 2020 15:41

Remove obsolete, unused code. (compare)

• Apr 28 2020 05:21

Rename sandbox to notebooks, fo… Add a violin plot case study. (compare)

• Apr 28 2020 04:13

Another attempt to tweak code h… (compare)

• Apr 28 2020 03:59

Tweaking language highlighting. (compare)

• Apr 28 2020 03:42

Switch to nbsphinx to integrate… (compare)

• Apr 22 2020 18:35
• Apr 22 2020 18:35
• Apr 22 2020 18:32

Bump version number after relea… (compare)

Eaton Lab
@eaton-lab
The first screencap above shows four three drawings. The first two are normal cartesian coordinates, the second two project polar coordinates into cartesian space. The last one uses curved edges, which wasn't yet supported in toyplot but I sort of kludged it together.
The SVG example below that is showing an example of a path element as an arc around a circle. This is something I want to support so I can add an arc around a circular tree to label parts of it.
But instead of kludging it together, I thought perhaps a more toyplot-like way to do this might be:
# in theory radial would plot x to angle or radians and y to radius
axes.plot([0, 25], [50, 25], color='blue')
Eaton Lab
@eaton-lab
but from looking at svg elements, its not clear to me how to create a filled rectangle element like a wedge using rect or polygon.
More generally, this type of radial figure is becoming quite popular, but is not easily implemented in common Python plotting tools. For example, to implement a chord plot in Python I've only found a few examples such as this one which requires holoviews and is overly complex IMO: https://holoviews.org/reference/elements/bokeh/Chord.html
Drawing a radial wedge in SVG is no problem, it’s just a filled path that contains alternating lines and arcs. Alternatively, you might be able to get away with just an arc, with a really wide stroke width. Mainly, I’m thinking through whether polar coordinates are sufficient for your use case. Refresh my memory: toytree is building a toyplot graph under the hood, is that right? And the toyplot graph contains more nodes and edges than the tree, in order to explicitly capture the layout? Assuming that’s correct, is toyplot doing all of the rendering once it’s a graph, or are you overriding that too?
Eaton Lab
@eaton-lab
I used to use a graph object, but since v2 I have written a custom ToyTreeMark object that is rendered with the toyplot dispatch _render call.
I see, makes sense about combining lines and arcs.
Here's the current custom Mark and render code for toytree: https://github.com/eaton-lab/toytree/blob/master/toytree/Render.py
Hah, I’m pretty jazzed to see a custom mark! I guess the real question is whether changing the projection is sufficient. I’m of a mind to stub-out a simple set of radial coordinates, and then let you provide feedback on whether it works or not.
As an aside, I’m of a mind to bump the version to 1.0 in the near future, and then revisit the design for version 2. I use Toyplot nearly every day, and there are things with which I’m very satisfied (explicit, predictable layout, consistent appearance whether in a notebook or a PDF), and things that are disappointing (web interaction never got very far, too slow for animation, Python still doesn’t have a decent, portable, vector drawing library).
Eaton Lab
@eaton-lab
Yes, writing the custom Mark was fun, and definitely helped me to better understand how toyplot works under-the-hood.
Eaton Lab
@eaton-lab
Congrats on the upcoming 1.0 milestone. I agree toyplot seems quite stable. I definitely promote it to a lot of people. I'd be happy to try out a new radial axes class and give feedback if you add a stub to v2 dev.
Eaton Lab
@eaton-lab
Hi @tshead , is there a simple way to modify the z-order of marks after a plot has been generated? Maybe by accessing the scenegraph?
Eaton Lab
@eaton-lab
for me the idea is to allow annotating a tree figure after the fact like the example here:
Eaton Lab
@eaton-lab
On a related note, it would be really cool to be able to support a linear gradient colormap to rectangle objects like in your documentation using toyplot.color.LinearMap. I would have a bunch of uses for this type of function if it were easier to use...
@eaton-lab - if by scenegraph you mean the XML tree, then yes - that would be the only practical way to do it. The only guarantees Toyplot provides WRT z-order is that the order in which marks are created affects their z-order in the obvious "painters’ algorithm" way.
I’m not following the confusion / issue with colormaps - are you wanting to draw a gradient, or having trouble mapping colors to rectangles? If it’s the latter, I could use an example.
As an aside, I’m thinking about moving a lot of the color / colormap related code into a separate, general purpose library, so feedback on what works / what doesn’t would be welcome.
Furthermore, my vague, ill-defined plans for Toyplot 2 are starting to come into focus. I have two new libraries - Graphcat and Imagecat - that are exploring this new direction. Graphcat - https://graphcat.readthedocs.io - is a general purpose library for managing computational graphs, and Imagecat - https://imagecat.readthedocs.io - uses those graphs to do image processing. I imagine that Toyplot 2 will also use Graphcat to organize rendering, simplifying a lot of complexity along the way, and making animation and interaction practical.
In this world, Toyplot would be a relatively thin API on top of a stack based on graphcat for overall workflow execution, imagecat for any image processing, and an as-yet-undesigned library for doing vector drawing, conversion to PDF, etc. @eaton-lab, I imagine that Toytree might ultimately use the same underlying stack, without having a dependency on Toyplot proper.
Eaton Lab
@eaton-lab
@tshead wow, that all sounds really amazing!
It’s fantastic in my mind, that’s for sure.
Eaton Lab
@eaton-lab
Here is an example canvas._scenegraph
<toyplot.scenegraph.SceneGraph at 0x7faa7e8bf3d0>
Relationship: render
<toyplot.canvas.Canvas object at 0x7faa43b59c50> ->
<toyplot.coordinates.Cartesian object at 0x7faa7e8bfc10>
<toyplot.coordinates.Cartesian object at 0x7faa7e8bfc10> ->
<toytree.Render.ToytreeMark object at 0x7faa434fe490>
<toyplot.mark.Range object at 0x7faa434fe050>
Relationship: map
<toyplot.coordinates.Axis object at 0x7faa7e8bfc90> ->
<toytree.Render.ToytreeMark object at 0x7faa434fe490>
<toyplot.mark.Range object at 0x7faa434fe050>
<toyplot.coordinates.Axis object at 0x7faa434febd0> ->
<toytree.Render.ToytreeMark object at 0x7faa434fe490>
<toyplot.mark.Range object at 0x7faa434fe050>
where I want to change the mark.Range object to appear below the Render.ToytreeMark object
... without having to change the order in which the plotting calls were made previously, if possible.
funny enough -- and completely unrelated to toyplot or toytree -- I have a student working on a project called simcat.
OK, I understand what you’re getting at with the scenegraph. Yes, you can reorder stuff under the “render” relationship, and it will have the desired effect - though you’re doing it in a way that I never anticipated.
Eaton Lab
@eaton-lab
Yeah, a bit kludgy, but this worked for me:
# put mark back on top of the axes z-order
axes._scenegraph.remove_edge(axes, 'render', mark)
axes._scenegraph.add_edge(axes, 'render', mark)
You’re using the public API, hard to do better. In a hypothetical Graphcat-enabled world, you would presumably assemble the graph yourself, using a set of primitive components provided by libraries.
Eaton Lab
@eaton-lab
Hi @tshead , I'm having trouble with aligning text with markers
canvas = toyplot.Canvas(width=500, height=150)
axes = canvas.cartesian(show=False)
axes.text(0, 0, "99", style={"font-size":"35px", "alignment-baseline": "alphabetic" })
axes.scatterplot(0, 0, color="black", size=10);
canvas = toyplot.Canvas(width=500, height=150)
axes = canvas.cartesian(show=False)
axes.text(0, 0, "99", style={"font-size":"35px", "alignment-baseline": "alphabetic" })
axes.scatterplot(0, 0, mstyle={"fill": "none", "stroke": "black"}, size=50);
I want it to align on the center of the text, whether it is upper case or lower... You can see in the latter example that it looks strange for integers, which are upper case, and do not align inside the marker. Is there a general style arg I can use to make this look nice whether for any labels: e.g., 'a', 'A', 99.
Eaton Lab
@eaton-lab
Eaton Lab
@eaton-lab
In toytree labels are usually integers (e.g., 100) and so they are always a little raised relative to the center of the circles that are usually plotted on nodes/vertices. It's fine if there is not easy solution, for now I can just shift labels down by a percentage, but I wanted to check. I messed around with baseline alignment and similar options for hours trying to figure it out.
Eaton Lab
@eaton-lab
@tshead is there a simple way to add css arguments to the top level <div> that would work with autorendering? For example, for certain types of very wide plots in notebooks (e.g., width=2000px) I would like to add width:2000px to the div style, which seems to allow for horizontal scrolling nicely in notebooks. I found I can make this work by rendering the HTML manually, but I can't figure out how to make this work with autorender. Thanks for your help
from IPython.display import HTML
HTML(toyplot.html.tostring(canvas, style={"text-align": "center", "width": "2000px"}))
Eaton Lab
@eaton-lab
Since autorender seems to rely on the _repr_html_ function, and the div style is hardcoded there, it looks like a reasonable solution would be to give Canvas a .div_style dict that could be modified and would be used in _repr_html_ instead of the fixed dict it currently uses. This could have {'text-align': 'center'} as its default and would perform the same unless modified by a user. Just an idea.
Eaton Lab
@eaton-lab
for anyone interested, creating a Canvas subclass worked for me to accomplish the above:
class ScrollableCanvas(toyplot.Canvas):
"""Canvas subclass with horizontal scrolling on large widths"""
def _repr_html_(self):
)