Adding interactivity to an histogram in SVG

Hi,

I'm trying to create an SVG figure that will show or hide the bars of
a histogram when clicking on the element in the legend. I got to the
point where it almost works...

I'm including the script so that others can play with it, but from
what I understand, the problem is that the first histogram patch
definition includes a clipping path definition

    <defs>
     <clipPath id="p7ff5b81e1d">
      <rect height="345.6" width="446.4" x="72.0" y="43.2" />
     </clipPath>
    </defs>

that is referenced by all other histogram patches. When setting the
visibility attribute of the first patch to "hidden" , it hides all
patches.

If I remove this clipping path entirely (by hand), the interactive
components work as expected.

This is my first foray in SVG so my approach is probably naive, but
I'd welcome suggestions to make this work. Having one clippath per
histogram item would simplify things, but I don't know the internals
of matplotlib well enough to do this elegantly.

Thanks,

David

hist_svg.py (2.77 KB)

I’m tinkering with your example a little bit, but clicking on the
legend items doesn’t seem to do anything whether it contains the
offending clipPath snippet or not. What version of matplotlib are
you using? What browser (and version) are you using to interact
with the SVG? Can you attach the SVG file (maybe in both working
and broken states), so I can tinker with it? You may want to try
moving the “” containing the clipPath up a level, so it
is a peer with the histogram rectangles. That’s just a stab in the
dark. If that turns out that makes the difference, that should be
an easy enough fix within matplotlib.

Cheers,
Mike
···

http://p.sf.net/sfu/wandisco-dev2dev


Matplotlib-devel@lists.sourceforge.nethttps://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Hi Mike,

Thanks for looking into this.

I'm tinkering with your example a little bit, but clicking on the legend
items doesn't seem to do anything whether it contains the offending clipPath
snippet or not. What version of matplotlib are you using?

I'm using matplotlib from git dating back to August 3.

What browser
(and version) are you using to interact with the SVG?

Chromium (12).

Can you attach the
SVG file (maybe in both working and broken states), so I can tinker with
it?

Here are two versions, one working as expected and the other with the glitch.

You may want to try moving the "<defs>" containing the clipPath up a

level, so it is a peer with the histogram rectangles.

Yep, that works.

That's just a stab in
the dark. If that turns out that makes the difference, that should be an
easy enough fix within matplotlib.

That would be great !

I'd be glad to contribute an example for the matplotlib gallery if
there is an interest. I think the SVG+JS combo has a lot of potential,
and matplotlib makes it easy.

Cheers,

David

hist_broken.svg

hist_working.svg

···

On Mon, Aug 22, 2011 at 5:52 PM, Michael Droettboom <mdroe@...31...> wrote:

You may want to try moving the "<defs>" containing the clipPath up a

level, so it is a peer with the histogram rectangles.

Yep, that works.

That's just a stab in
the dark. If that turns out that makes the difference, that should be an
easy enough fix within matplotlib.

That would be great !

I have a fix on this branch here:

https://github.com/mdboom/matplotlib/tree/svg_references

Would you mind testing it?

I'd be glad to contribute an example for the matplotlib gallery if
there is an interest. I think the SVG+JS combo has a lot of potential,
and matplotlib makes it easy.

That would make a great addition. One small comment: I would put the "onclick" handler on the legend handles as well as the legend text. I tried to click the legend handles (with nothing happening) until I realized the "hotspot" was only on the text.

For a long time, I have considered having a framework where arbitrary XML attributes can be assigned to artists and written out directly by the SVG writer to avoid the two-pass approach you're using here. (There is already support for assigning hyperlinks to SVG documents, but that could be made more general). But that will require some careful design consideration etc. to get it done. In the meantime, it's useful having an example that shows how to do this using ElementTree to modify the SVG after matplotlib outputs it.

Cheers,
Mike

···

On 08/23/2011 10:06 AM, David Huard wrote:

You may want to try moving the "<defs>" containing the clipPath up a

level, so it is a peer with the histogram rectangles.

Yep, that works.

That's just a stab in
the dark. If that turns out that makes the difference, that should be an
easy enough fix within matplotlib.

That would be great !

I have a fix on this branch here:

https://github.com/mdboom/matplotlib/tree/svg_references

Would you mind testing it?

Works like a charm !

I'd be glad to contribute an example for the matplotlib gallery if
there is an interest. I think the SVG+JS combo has a lot of potential,
and matplotlib makes it easy.

That would make a great addition. One small comment: I would put the
"onclick" handler on the legend handles as well as the legend text. I
tried to click the legend handles (with nothing happening) until I
realized the "hotspot" was only on the text.

Right, done.

For a long time, I have considered having a framework where arbitrary
XML attributes can be assigned to artists and written out directly by
the SVG writer to avoid the two-pass approach you're using here. (There
is already support for assigning hyperlinks to SVG documents, but that
could be made more general).

I thought about this too. There is already a set_gid method, so I
guess generalizing this to any (attribute, value) pair should not be
too hard. On the other hand, what would also help is more hierarchy
within the svg tree. At the moment, a group is created for figure,
axes, axis, legend and collections (from a quick overview, maybe there
are others.) However, since histogram returns flat patches instead of
a collection of patches, we need to loop through all bar patches to
set their properties. If histogram returned one patchcollection per
variable, we could address this group directly instead of the
individual elements.

But that will require some careful design
consideration etc. to get it done. In the meantime, it's useful having
an example that shows how to do this using ElementTree to modify the SVG
after matplotlib outputs it.

Good, I'll work on this then.

Thanks,

David

···

On Tue, Aug 23, 2011 at 11:29 AM, Michael Droettboom <mdroe@...31...> wrote:

On 08/23/2011 10:06 AM, David Huard wrote:

Cheers,
Mike

------------------------------------------------------------------------------
Get a FREE DOWNLOAD! and learn more about uberSVN rich system,
user administration capabilities and model configuration. Take
the hassle out of deploying and managing Subversion and the
tools developers use with it. http://p.sf.net/sfu/wandisco-d2d-2
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Mike,

I forked your branch and created this one which includes the revised
histogram example.

https://github.com/huard/matplotlib/tree/interactive_svg

Cheers

David

···

On Tue, Aug 23, 2011 at 1:37 PM, David Huard <david.huard@...149...> wrote:

On Tue, Aug 23, 2011 at 11:29 AM, Michael Droettboom <mdroe@...31...> wrote:

On 08/23/2011 10:06 AM, David Huard wrote:

You may want to try moving the "<defs>" containing the clipPath up a

level, so it is a peer with the histogram rectangles.

Yep, that works.

That's just a stab in
the dark. If that turns out that makes the difference, that should be an
easy enough fix within matplotlib.

That would be great !

I have a fix on this branch here:

https://github.com/mdboom/matplotlib/tree/svg_references

Would you mind testing it?

Works like a charm !

I'd be glad to contribute an example for the matplotlib gallery if
there is an interest. I think the SVG+JS combo has a lot of potential,
and matplotlib makes it easy.

That would make a great addition. One small comment: I would put the
"onclick" handler on the legend handles as well as the legend text. I
tried to click the legend handles (with nothing happening) until I
realized the "hotspot" was only on the text.

Right, done.

For a long time, I have considered having a framework where arbitrary
XML attributes can be assigned to artists and written out directly by
the SVG writer to avoid the two-pass approach you're using here. (There
is already support for assigning hyperlinks to SVG documents, but that
could be made more general).

I thought about this too. There is already a set_gid method, so I
guess generalizing this to any (attribute, value) pair should not be
too hard. On the other hand, what would also help is more hierarchy
within the svg tree. At the moment, a group is created for figure,
axes, axis, legend and collections (from a quick overview, maybe there
are others.) However, since histogram returns flat patches instead of
a collection of patches, we need to loop through all bar patches to
set their properties. If histogram returned one patchcollection per
variable, we could address this group directly instead of the
individual elements.

But that will require some careful design
consideration etc. to get it done. In the meantime, it's useful having
an example that shows how to do this using ElementTree to modify the SVG
after matplotlib outputs it.

Good, I'll work on this then.

Thanks,

David

Cheers,
Mike

------------------------------------------------------------------------------
Get a FREE DOWNLOAD! and learn more about uberSVN rich system,
user administration capabilities and model configuration. Take
the hassle out of deploying and managing Subversion and the
tools developers use with it. http://p.sf.net/sfu/wandisco-d2d-2
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel