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

Intermittent SVG error in the notebook #8133

Closed
moble opened this Issue Mar 24, 2015 · 26 comments

Comments

Projects
None yet
6 participants
@moble

moble commented Mar 24, 2015

I have long had a problem with SVG matplotlib output in the notebook. Intermittently, the plot will extend outside of the axes, as exemplified in this screenshot:

matplotlibsvgnotebookbug

Basically, everything below the horizontal axis should be hidden. Most of the time, it is properly hidden -- e.g., when the plot is first made, or when I collapse and expand the output area. But then sometimes, it'll go buggy like this. I can't reproduce this consistently, but it seems to happen most often when I make a plot in another cell.

That stuff that's usually hidden evidently does correspond to actual data; when I plot again with xlim(xmin=1e-18), the data does show up just like that, except that it is correctly based at 1e-18. So it's evidently really in the SVG.

I'm wondering if this is related to #1881 and #2647, but none of the descriptions of problems there were specific enough. Is this expected badness in the matplotlib output?

I've had this problem for a long time (years?), but I can verify that it exists currently in IPython 3.0.0. I'm seeing it in up-to-date Chrome and Safari on up-to-date OS X, using an up-to-date anaconda installation (python 2.7). Here are the IPython details:

{'commit_hash': u'f75fda4',
'commit_source': 'installation',
'default_encoding': 'UTF-8',
'ipython_path': ..../anaconda/lib/python2.7/site-packages/IPython',
'ipython_version': '3.0.0',
'os_name': 'posix',
'platform': 'Darwin-14.1.0-x86_64-i386-64bit',
'sys_executable': '/Users/boyle/.continuum/anaconda/bin/python',
'sys_platform': 'darwin',
'sys_version': '2.7.9 |Continuum Analytics, Inc.| (default, Dec 15 2014, 10:37:34) \n[GCC 4.2.1 (Apple Inc. build 5577)]'}

@rsmith31415

This comment has been minimized.

Show comment
Hide comment
@rsmith31415

rsmith31415 Mar 24, 2015

Contributor

Would you be able to provide sample code that reproduces (even if intermittently) this issue?

Contributor

rsmith31415 commented Mar 24, 2015

Would you be able to provide sample code that reproduces (even if intermittently) this issue?

@moble

This comment has been minimized.

Show comment
Hide comment
@moble

moble Mar 24, 2015

Ah, yes I can! And it's even reproducible! I've never been able to make this reproducible before.

Open this notebook. You might have to evaluate the cells to make sure the output is actually SVG; if so I don't know of any way to do this without the following line in ipython_config.py:

c.InlineBackend.figure_format = 'svg'

Anyway, once you've got all three figures as SVG, delete the middle one. This does it every time for me. The badness also happens for me in existing figures when I'm evaluating a new one.

moble commented Mar 24, 2015

Ah, yes I can! And it's even reproducible! I've never been able to make this reproducible before.

Open this notebook. You might have to evaluate the cells to make sure the output is actually SVG; if so I don't know of any way to do this without the following line in ipython_config.py:

c.InlineBackend.figure_format = 'svg'

Anyway, once you've got all three figures as SVG, delete the middle one. This does it every time for me. The badness also happens for me in existing figures when I'm evaluating a new one.

@rsmith31415

This comment has been minimized.

Show comment
Hide comment
@rsmith31415

rsmith31415 Mar 25, 2015

Contributor

Thank you. I also can reproduce it . Very interesting bug.

First of all, let me simplify your example:

import numpy as nps
import matplotlib as mpl
import matplotlib.pyplot as plt
%config InlineBackend.figure_format = 'svg'
%matplotlib inline
size=2

plt.hist(np.random.random(size), log=True) # run in one cell

plt.hist(np.random.random(size), log=True) # run in another cell

Now delete the first one and look at the second plot. The issue should appear.

The interesting thing is that this only happens when:

  1. We are plotting in logarithmic scale (log=True).
  2. The plot that is deleted has the same type than the second plot. If we use plt.bar and plt.hist, the second plot is not modified after deleting the first. The second plot is also restored after printing another plot of the same type.
  3. Using Chrome. In Firefox, everything looks alright.

Before deleting the first plot:

screenshot from 2015-03-24 17 44 40

After deleting the first plot:

screenshot from 2015-03-24 17 44 55

After printing another plot of different type:

screenshot from 2015-03-24 17 45 21

After printing another plot of the same type (in this case, plt.hist):

screenshot from 2015-03-24 17 45 39

After diffing the whole HTML of the notebook before and after deleting the first plot, I wasn't able to find a significant difference. The paths are the same and axes don't seem to be modified. The positions of the paths seem to change (or the axes) but that wasn't reflected in the diff. The only thing I noticed that might cause issues is that every svg plot has the same ids. For example:

 <g id="figure_1">    
        <g id="patch_1">...</g>
        <g id="axes_1>...</g>
 </g>

but I don't think that is the problem here.

Contributor

rsmith31415 commented Mar 25, 2015

Thank you. I also can reproduce it . Very interesting bug.

First of all, let me simplify your example:

import numpy as nps
import matplotlib as mpl
import matplotlib.pyplot as plt
%config InlineBackend.figure_format = 'svg'
%matplotlib inline
size=2

plt.hist(np.random.random(size), log=True) # run in one cell

plt.hist(np.random.random(size), log=True) # run in another cell

Now delete the first one and look at the second plot. The issue should appear.

The interesting thing is that this only happens when:

  1. We are plotting in logarithmic scale (log=True).
  2. The plot that is deleted has the same type than the second plot. If we use plt.bar and plt.hist, the second plot is not modified after deleting the first. The second plot is also restored after printing another plot of the same type.
  3. Using Chrome. In Firefox, everything looks alright.

Before deleting the first plot:

screenshot from 2015-03-24 17 44 40

After deleting the first plot:

screenshot from 2015-03-24 17 44 55

After printing another plot of different type:

screenshot from 2015-03-24 17 45 21

After printing another plot of the same type (in this case, plt.hist):

screenshot from 2015-03-24 17 45 39

After diffing the whole HTML of the notebook before and after deleting the first plot, I wasn't able to find a significant difference. The paths are the same and axes don't seem to be modified. The positions of the paths seem to change (or the axes) but that wasn't reflected in the diff. The only thing I noticed that might cause issues is that every svg plot has the same ids. For example:

 <g id="figure_1">    
        <g id="patch_1">...</g>
        <g id="axes_1>...</g>
 </g>

but I don't think that is the problem here.

@moble

This comment has been minimized.

Show comment
Hide comment
@moble

moble Mar 25, 2015

After diffing the whole HTML of the notebook before and after deleting the first plot, I wasn't able to find a significant difference.

Yeah, I'd doubt that it'd be HTML; it comes and goes (and comes and goes again) depending on various actions in the notebook.

I think it's really just that the data points are failing to be clipped by the axes rectangle. But why this should fail intermittently is the question.

Another data point: I can use just plain plots, with no log scaling, and get extra data to appear on all four sides of the axes:

matplotlibsvgnotebookbug2

So I guess it's just a generic feature of the SVG, whenever the range of the data being plotted is larger than the range of the xlim and ylim values.

moble commented Mar 25, 2015

After diffing the whole HTML of the notebook before and after deleting the first plot, I wasn't able to find a significant difference.

Yeah, I'd doubt that it'd be HTML; it comes and goes (and comes and goes again) depending on various actions in the notebook.

I think it's really just that the data points are failing to be clipped by the axes rectangle. But why this should fail intermittently is the question.

Another data point: I can use just plain plots, with no log scaling, and get extra data to appear on all four sides of the axes:

matplotlibsvgnotebookbug2

So I guess it's just a generic feature of the SVG, whenever the range of the data being plotted is larger than the range of the xlim and ylim values.

@moble

This comment has been minimized.

Show comment
Hide comment
@moble

moble Mar 25, 2015

I should also point out that I used a completely new profile to do this, with absolutely no changes to ipython_config.py, custom.js, etc.

moble commented Mar 25, 2015

I should also point out that I used a completely new profile to do this, with absolutely no changes to ipython_config.py, custom.js, etc.

@rsmith31415

This comment has been minimized.

Show comment
Hide comment
@rsmith31415

rsmith31415 Mar 25, 2015

Contributor

Okay. I still can't decide who is at fault here. This is the evidence so far:

If you delete the node that contains the first plot (that is, delete its SVG information) using the Developer Tools in Chrome, then you obtain the same bug.

Now, after copying (twice) the SVG code to a HTML file and opening the file in Chrome, you get a huge plot (due to width: 100%; and height: 100%;). Try to delete the first plot (again with the Developer Tools) and at first nothing wrong happens, but zoom-in or zoom-out and you're going to obtain the same bug:

screenshot from 2015-03-24 21 31 09

By the way, after that, I removed the additional properties that Ipython is including in the SVG. The reason is that Firefox wasn't rendering correctly the plots. I don't think most of them are needed anyway.

Firefox (after removing additional attributes in SVG):
screenshot from 2015-03-24 21 33 08

That seems upside down. However, if I zoom in, I get this:

screenshot from 2015-03-24 21 36 27

When I zoom in even further the plot switches between bars starting from the top and the bottom.

In Chrome, we get more consistency (even though the plot is wrong)

screenshot from 2015-03-24 22 14 57

I'm thinking the generated plots might not be valid SVG (or at least, they are obviously not standard). That could be the problem. Does anyone know a good SVG validator? I found a couple but the results were not satisfactory. One of them pointed out that the SVG has one error in the property xlink:href in this line: <use style="stroke:#000000;stroke-width:0.5;" x="30.5" xlink:href="#m93b0483c22" y="230.4"></use> but I'm not completely convinced about it.

Contributor

rsmith31415 commented Mar 25, 2015

Okay. I still can't decide who is at fault here. This is the evidence so far:

If you delete the node that contains the first plot (that is, delete its SVG information) using the Developer Tools in Chrome, then you obtain the same bug.

Now, after copying (twice) the SVG code to a HTML file and opening the file in Chrome, you get a huge plot (due to width: 100%; and height: 100%;). Try to delete the first plot (again with the Developer Tools) and at first nothing wrong happens, but zoom-in or zoom-out and you're going to obtain the same bug:

screenshot from 2015-03-24 21 31 09

By the way, after that, I removed the additional properties that Ipython is including in the SVG. The reason is that Firefox wasn't rendering correctly the plots. I don't think most of them are needed anyway.

Firefox (after removing additional attributes in SVG):
screenshot from 2015-03-24 21 33 08

That seems upside down. However, if I zoom in, I get this:

screenshot from 2015-03-24 21 36 27

When I zoom in even further the plot switches between bars starting from the top and the bottom.

In Chrome, we get more consistency (even though the plot is wrong)

screenshot from 2015-03-24 22 14 57

I'm thinking the generated plots might not be valid SVG (or at least, they are obviously not standard). That could be the problem. Does anyone know a good SVG validator? I found a couple but the results were not satisfactory. One of them pointed out that the SVG has one error in the property xlink:href in this line: <use style="stroke:#000000;stroke-width:0.5;" x="30.5" xlink:href="#m93b0483c22" y="230.4"></use> but I'm not completely convinced about it.

@takluyver

This comment has been minimized.

Show comment
Hide comment
@takluyver

takluyver Mar 25, 2015

Member
Member

takluyver commented Mar 25, 2015

@rsmith31415

This comment has been minimized.

Show comment
Hide comment
@rsmith31415

rsmith31415 Mar 25, 2015

Contributor

@takluyver Very unlikely. As an example, the New York Times is full of SVGs and work very well. caniuse shows that support among browsers is reasonable. I also tested Mike Bostock's example of a histogram (copied the d3 code twice to generate two histograms) and the bug didn't appear, although the example is admittedly very simple.

I think the main indicator that the generated SVG might be suboptimal is that Firefox and Chrome have different issues displaying it. As I said, I had to remove many attributes in the SVG tag because Firefox didn't want to render the plots. However, the picture is complicated by the fact that Firefox rendered the plots correctly within the notebook.

Contributor

rsmith31415 commented Mar 25, 2015

@takluyver Very unlikely. As an example, the New York Times is full of SVGs and work very well. caniuse shows that support among browsers is reasonable. I also tested Mike Bostock's example of a histogram (copied the d3 code twice to generate two histograms) and the bug didn't appear, although the example is admittedly very simple.

I think the main indicator that the generated SVG might be suboptimal is that Firefox and Chrome have different issues displaying it. As I said, I had to remove many attributes in the SVG tag because Firefox didn't want to render the plots. However, the picture is complicated by the fact that Firefox rendered the plots correctly within the notebook.

@moble

This comment has been minimized.

Show comment
Hide comment
@moble

moble Mar 25, 2015

Safari has the same problem as Chrome, so I'd be a little surprised if it's a rendering bug -- though not hugely surprised.

BTW I've boiled it down to a particularly simple test case:

plt.plot([0, 1], [0, 1])
plt.xlim(0.1, 0.9)
plt.ylim(0.1, 0.9);

moble commented Mar 25, 2015

Safari has the same problem as Chrome, so I'd be a little surprised if it's a rendering bug -- though not hugely surprised.

BTW I've boiled it down to a particularly simple test case:

plt.plot([0, 1], [0, 1])
plt.xlim(0.1, 0.9)
plt.ylim(0.1, 0.9);
@takluyver

This comment has been minimized.

Show comment
Hide comment
@takluyver

takluyver Mar 25, 2015

Member

Safari and Chrome both use the Webkit rendering engine (technically, Chrome uses Blink, which is a fork of Webkit), so it's possible that they are inheriting the same underlyign bug.

Member

takluyver commented Mar 25, 2015

Safari and Chrome both use the Webkit rendering engine (technically, Chrome uses Blink, which is a fork of Webkit), so it's possible that they are inheriting the same underlyign bug.

@rsmith31415

This comment has been minimized.

Show comment
Hide comment
@rsmith31415

rsmith31415 Mar 25, 2015

Contributor

Yes, Safari and Chrome are likely to share the same bug. In my opinion, the best argument in favor of a browser bug is that the second SVG code is not changing at all after deleting the first plot. On the other hand, I tried to replicate the bug with this histogram from Wikipedia but no luck so far.

There might be a middle ground, though. We are generating a tricky SVG to handle. It is using a lot of paths for things that are better done using rect or polygon and adding properties that are not necessary when rendering HTML documents. Maybe that is exposing some bug in the browsers. However, it is also difficult to explain why it is exposing different bugs and at least in Firefox, overall unstable behavior. Furthermore, we are generating different SVGs (bar, hist, plot) and all of them reproduce the same issue. Assuming our SVGs are correct, that's quite a coincidence.

It is also interesting that the example using plot can reproduce this issue but removing log=True in the other examples avoids the problem.

Contributor

rsmith31415 commented Mar 25, 2015

Yes, Safari and Chrome are likely to share the same bug. In my opinion, the best argument in favor of a browser bug is that the second SVG code is not changing at all after deleting the first plot. On the other hand, I tried to replicate the bug with this histogram from Wikipedia but no luck so far.

There might be a middle ground, though. We are generating a tricky SVG to handle. It is using a lot of paths for things that are better done using rect or polygon and adding properties that are not necessary when rendering HTML documents. Maybe that is exposing some bug in the browsers. However, it is also difficult to explain why it is exposing different bugs and at least in Firefox, overall unstable behavior. Furthermore, we are generating different SVGs (bar, hist, plot) and all of them reproduce the same issue. Assuming our SVGs are correct, that's quite a coincidence.

It is also interesting that the example using plot can reproduce this issue but removing log=True in the other examples avoids the problem.

@moble

This comment has been minimized.

Show comment
Hide comment
@moble

moble Mar 25, 2015

It is also interesting that the example using plot can reproduce this issue but removing log=True in the other examples avoids the problem.

I think that's just a coincidence of the limits. With log=False, the bars of the histogram range between y=0 and y=1 (or higher), but the limits also go from y=0 to y=1 (or higher), so all of the plotted stuff is within the limits, and there's nothing to be displayed incorrectly. With log=True, the bars extend infinitely(ish) far down, but the ylimit has some finite minimum, so the bars can be accidentally displayed.

That's why I think plot is the more useful case; as long as there's data outside the limits, it looks like there's potential for that data to be accidentally displayed.

moble commented Mar 25, 2015

It is also interesting that the example using plot can reproduce this issue but removing log=True in the other examples avoids the problem.

I think that's just a coincidence of the limits. With log=False, the bars of the histogram range between y=0 and y=1 (or higher), but the limits also go from y=0 to y=1 (or higher), so all of the plotted stuff is within the limits, and there's nothing to be displayed incorrectly. With log=True, the bars extend infinitely(ish) far down, but the ylimit has some finite minimum, so the bars can be accidentally displayed.

That's why I think plot is the more useful case; as long as there's data outside the limits, it looks like there's potential for that data to be accidentally displayed.

@rsmith31415

This comment has been minimized.

Show comment
Hide comment
@rsmith31415

rsmith31415 Mar 25, 2015

Contributor

@moble You're quite right. I found something interesting using this minimal example:

plt.plot([0.5], [0.5], 'bo')
plt.xlim(0, 0.5)

I copied twice the SVG code:

screenshot from 2015-03-25 13 52 37

but now, I deleted the first node <defs>:

<defs>
  <style type="text/css">
 *{stroke-linecap:butt;stroke-linejoin:round;}
  </style>
</defs>

in both SVGs. Then I delete the first SVG. The resulting image is finally correct:

screenshot from 2015-03-25 13 55 54

If I delete, for example, the last <defs> or a path, the bug persists:

screenshot from 2015-03-25 13 57 45

UPDATE: Forgot to clarify: The rule inside <defs> is the problem, not the tag or <script>.

Contributor

rsmith31415 commented Mar 25, 2015

@moble You're quite right. I found something interesting using this minimal example:

plt.plot([0.5], [0.5], 'bo')
plt.xlim(0, 0.5)

I copied twice the SVG code:

screenshot from 2015-03-25 13 52 37

but now, I deleted the first node <defs>:

<defs>
  <style type="text/css">
 *{stroke-linecap:butt;stroke-linejoin:round;}
  </style>
</defs>

in both SVGs. Then I delete the first SVG. The resulting image is finally correct:

screenshot from 2015-03-25 13 55 54

If I delete, for example, the last <defs> or a path, the bug persists:

screenshot from 2015-03-25 13 57 45

UPDATE: Forgot to clarify: The rule inside <defs> is the problem, not the tag or <script>.

@rsmith31415

This comment has been minimized.

Show comment
Hide comment
@rsmith31415

rsmith31415 Apr 3, 2015

Contributor

@moble @takluyver Can you replicate the observation that removing the rule inside <defs> solves this issue?

Contributor

rsmith31415 commented Apr 3, 2015

@moble @takluyver Can you replicate the observation that removing the rule inside <defs> solves this issue?

@moble

This comment has been minimized.

Show comment
Hide comment
@moble

moble Apr 4, 2015

No, it doesn't work for me -- unless I'm misunderstanding you. I tried your experiment of copying the SVG twice into an HTML file, then delete one using developer tools. I got the out-of-bounds lines. Then I went into the HTML file and deleted the <defs> sections from both SVGs, full refreshed the page, deleted one, and zoomed, and I saw the problem again. You can see in my screenshot that the defs section isn't there:

screenshot

moble commented Apr 4, 2015

No, it doesn't work for me -- unless I'm misunderstanding you. I tried your experiment of copying the SVG twice into an HTML file, then delete one using developer tools. I got the out-of-bounds lines. Then I went into the HTML file and deleted the <defs> sections from both SVGs, full refreshed the page, deleted one, and zoomed, and I saw the problem again. You can see in my screenshot that the defs section isn't there:

screenshot

@rsmith31415

This comment has been minimized.

Show comment
Hide comment
@rsmith31415

rsmith31415 Apr 4, 2015

Contributor

@moble Interesting. Let me try again.

Contributor

rsmith31415 commented Apr 4, 2015

@moble Interesting. Let me try again.

@rsmith31415

This comment has been minimized.

Show comment
Hide comment
@rsmith31415

rsmith31415 Apr 4, 2015

Contributor

@moble Okay. I have reproduced the problem in a very simple SVG:

<svg width="120" height="120"
     viewPort="0 0 120 120" version="1.1"
     xmlns="http://www.w3.org/2000/svg">

    <defs>
        <clipPath id="myClip" >
            <rect x="0" y="0" width="97" height="97" />
        </clipPath>
    </defs>
    <g clip-path="url(#myClip)">
        <rect x="0" y="0" width="100" height="100" fill="blue" />
        <circle cx="97" cy="50" r="5" fill="red"/> 
    </g>
</svg>


<svg width="120" height="120"
     viewPort="0 0 120 120" version="1.1"
     xmlns="http://www.w3.org/2000/svg">

    <defs>
        <clipPath id="myClip" >
            <rect x="0" y="0" width="97" height="97" />
        </clipPath>
    </defs>
    <g clip-path="url(#myClip)">
        <rect x="0" y="0" width="100" height="100" fill="blue" />
        <circle cx="97" cy="50" r="5" fill="red"/> 
    </g>
</svg>

In the developer tools, delete one of the figures and zoom in. The circle will be shown outside of the boundary.

I can't explain exactly what is happening, but the problem is related to the clipping mask applied in <defs>. When we zoom in (or zoom out), the clipping mask doesn't seem to scale correctly but this only happens after removing one of the figures. The issue here is that both figures have the same id property for the clipPath element. If you change one of them (e.g. <clipPath id="myClip2">), then this issue should be solved (remember also change it in <g clip-path="url(#myClip2)">).

Before:

screenshot from 2015-04-04 00 28 22

After:

screenshot from 2015-04-04 00 30 38

Contributor

rsmith31415 commented Apr 4, 2015

@moble Okay. I have reproduced the problem in a very simple SVG:

<svg width="120" height="120"
     viewPort="0 0 120 120" version="1.1"
     xmlns="http://www.w3.org/2000/svg">

    <defs>
        <clipPath id="myClip" >
            <rect x="0" y="0" width="97" height="97" />
        </clipPath>
    </defs>
    <g clip-path="url(#myClip)">
        <rect x="0" y="0" width="100" height="100" fill="blue" />
        <circle cx="97" cy="50" r="5" fill="red"/> 
    </g>
</svg>


<svg width="120" height="120"
     viewPort="0 0 120 120" version="1.1"
     xmlns="http://www.w3.org/2000/svg">

    <defs>
        <clipPath id="myClip" >
            <rect x="0" y="0" width="97" height="97" />
        </clipPath>
    </defs>
    <g clip-path="url(#myClip)">
        <rect x="0" y="0" width="100" height="100" fill="blue" />
        <circle cx="97" cy="50" r="5" fill="red"/> 
    </g>
</svg>

In the developer tools, delete one of the figures and zoom in. The circle will be shown outside of the boundary.

I can't explain exactly what is happening, but the problem is related to the clipping mask applied in <defs>. When we zoom in (or zoom out), the clipping mask doesn't seem to scale correctly but this only happens after removing one of the figures. The issue here is that both figures have the same id property for the clipPath element. If you change one of them (e.g. <clipPath id="myClip2">), then this issue should be solved (remember also change it in <g clip-path="url(#myClip2)">).

Before:

screenshot from 2015-04-04 00 28 22

After:

screenshot from 2015-04-04 00 30 38

@moble

This comment has been minimized.

Show comment
Hide comment
@moble

moble Apr 4, 2015

That certainly explains that. And for the naive MWE above, I can verify that the clipPath id is the same in each case. But then, I can also change the parameters of the graph and get the same clipPath. So apparently, either whatever is being hashed to produce the id either isn't complete enough, or the hash isn't updated for changes in the plot. Any idea where that id comes from?

moble commented Apr 4, 2015

That certainly explains that. And for the naive MWE above, I can verify that the clipPath id is the same in each case. But then, I can also change the parameters of the graph and get the same clipPath. So apparently, either whatever is being hashed to produce the id either isn't complete enough, or the hash isn't updated for changes in the plot. Any idea where that id comes from?

@rsmith31415

This comment has been minimized.

Show comment
Hide comment
@rsmith31415

rsmith31415 Apr 4, 2015

Contributor

@moble

Sure. id is created here. As you can see, matplotlib is only using content information in the hash. I think a solution would be to include an extra parameter with a randomly generated value to prevent the current bug. However, they could be relying on the current behavior in some tests, so it is better to open an issue and let them know what is happening.

@takluyver I think you can close this issue in favor of opening another in the matplotlib repository.

Contributor

rsmith31415 commented Apr 4, 2015

@moble

Sure. id is created here. As you can see, matplotlib is only using content information in the hash. I think a solution would be to include an extra parameter with a randomly generated value to prevent the current bug. However, they could be relying on the current behavior in some tests, so it is better to open an issue and let them know what is happening.

@takluyver I think you can close this issue in favor of opening another in the matplotlib repository.

@abreslow

This comment has been minimized.

Show comment
Hide comment

abreslow commented Apr 14, 2015

@rsmith31415

This comment has been minimized.

Show comment
Hide comment
@rsmith31415

rsmith31415 Apr 14, 2015

Contributor

@abreslow Well, I think your problem is not really related with this particular issue and your code works okay in the IPython Notebook. However, this is the problem:

Your SVG is defining a clipping mask at the end of the file:

 <defs>
  <clipPath id="p124b8dd147">
   <rect height="223.2" width="334.8" x="54.0" y="28.8"/>
  </clipPath>
 </defs>

The browser seems to be flexible about this, but you usually want to create your definitions <defs> at the top of the SVG code. Unfortunately, matplotlib is placing clipping masks at the bottom and this is causing your problem. For example, if you move your clipping mask as follows:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Created with matplotlib (http://matplotlib.org/) -->
<svg height="288pt" version="1.1" viewBox="0 0 432 288" width="432pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 <defs>
  <style type="text/css">
*{stroke-linecap:butt;stroke-linejoin:round;}
  </style>
 </defs>
 <defs>
  <clipPath id="p124b8dd147">
   <rect height="223.2" width="334.8" x="54.0" y="28.8"/>
  </clipPath>
 </defs>

you will see the correct plot:

screenshot from 2015-04-14 15 29 30

Even trivial examples such as this:

<?xml version="1.0"?>
<svg width="120" height="120"
     viewPort="0 0 120 120" version="1.1"
     xmlns="http://www.w3.org/2000/svg">

    <defs>
        <clipPath id="myClip">
            <circle cx="30" cy="30" r="20"/>
            <circle cx="70" cy="70" r="20"/>
        </clipPath>
    </defs>

    <rect x="10" y="10" width="100" height="100"
          clip-path="url(#myClip)"/>

</svg>

will fail if you put your clipping mask at the bottom.

Contributor

rsmith31415 commented Apr 14, 2015

@abreslow Well, I think your problem is not really related with this particular issue and your code works okay in the IPython Notebook. However, this is the problem:

Your SVG is defining a clipping mask at the end of the file:

 <defs>
  <clipPath id="p124b8dd147">
   <rect height="223.2" width="334.8" x="54.0" y="28.8"/>
  </clipPath>
 </defs>

The browser seems to be flexible about this, but you usually want to create your definitions <defs> at the top of the SVG code. Unfortunately, matplotlib is placing clipping masks at the bottom and this is causing your problem. For example, if you move your clipping mask as follows:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Created with matplotlib (http://matplotlib.org/) -->
<svg height="288pt" version="1.1" viewBox="0 0 432 288" width="432pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 <defs>
  <style type="text/css">
*{stroke-linecap:butt;stroke-linejoin:round;}
  </style>
 </defs>
 <defs>
  <clipPath id="p124b8dd147">
   <rect height="223.2" width="334.8" x="54.0" y="28.8"/>
  </clipPath>
 </defs>

you will see the correct plot:

screenshot from 2015-04-14 15 29 30

Even trivial examples such as this:

<?xml version="1.0"?>
<svg width="120" height="120"
     viewPort="0 0 120 120" version="1.1"
     xmlns="http://www.w3.org/2000/svg">

    <defs>
        <clipPath id="myClip">
            <circle cx="30" cy="30" r="20"/>
            <circle cx="70" cy="70" r="20"/>
        </clipPath>
    </defs>

    <rect x="10" y="10" width="100" height="100"
          clip-path="url(#myClip)"/>

</svg>

will fail if you put your clipping mask at the bottom.

@abreslow

This comment has been minimized.

Show comment
Hide comment
@abreslow

abreslow Apr 15, 2015

Thanks @rsmith31415.

On Tue, Apr 14, 2015 at 1:34 PM, rsmith31415 notifications@github.com
wrote:

@abreslow https://github.com/abreslow Well, I think your problem is not
really related with this particular issue and your code works okay in the
IPython Notebook. However, this is the problem:

Your SVG is defining a clipping mask at the end of the file:

The browser seems to be flexible about this, but you usually want to
create your definitions at the top of the SVG code. Unfortunately,
matplotlib is placing clipping masks at the bottom and this is causing your
problem. For example, if you move your clipping mask as follows:

<style type="text/css"> *{stroke-linecap:butt;stroke-linejoin:round;} </style>

you will see the correct plot:

[image: screenshot from 2015-04-14 15 29 30]
https://cloud.githubusercontent.com/assets/599274/7146695/11f715a8-e2bb-11e4-9dd6-5deba796039e.png

Even trivial examples such as this:

<defs>
    <clipPath id="myClip">
        <circle cx="30" cy="30" r="20"/>
        <circle cx="70" cy="70" r="20"/>
    </clipPath>
</defs>

<rect x="10" y="10" width="100" height="100"
      clip-path="url(#myClip)"/>

will fail if you put your clipping mask at the bottom.


Reply to this email directly or view it on GitHub
#8133 (comment).

Alex Breslow
PhD student in computer science at UC San Diego
Email: abreslow@cs.ucsd.edu
Website: cseweb.ucsd.edu/~abreslow

abreslow commented Apr 15, 2015

Thanks @rsmith31415.

On Tue, Apr 14, 2015 at 1:34 PM, rsmith31415 notifications@github.com
wrote:

@abreslow https://github.com/abreslow Well, I think your problem is not
really related with this particular issue and your code works okay in the
IPython Notebook. However, this is the problem:

Your SVG is defining a clipping mask at the end of the file:

The browser seems to be flexible about this, but you usually want to
create your definitions at the top of the SVG code. Unfortunately,
matplotlib is placing clipping masks at the bottom and this is causing your
problem. For example, if you move your clipping mask as follows:

<style type="text/css"> *{stroke-linecap:butt;stroke-linejoin:round;} </style>

you will see the correct plot:

[image: screenshot from 2015-04-14 15 29 30]
https://cloud.githubusercontent.com/assets/599274/7146695/11f715a8-e2bb-11e4-9dd6-5deba796039e.png

Even trivial examples such as this:

<defs>
    <clipPath id="myClip">
        <circle cx="30" cy="30" r="20"/>
        <circle cx="70" cy="70" r="20"/>
    </clipPath>
</defs>

<rect x="10" y="10" width="100" height="100"
      clip-path="url(#myClip)"/>

will fail if you put your clipping mask at the bottom.


Reply to this email directly or view it on GitHub
#8133 (comment).

Alex Breslow
PhD student in computer science at UC San Diego
Email: abreslow@cs.ucsd.edu
Website: cseweb.ucsd.edu/~abreslow

@rsmith31415

This comment has been minimized.

Show comment
Hide comment
@rsmith31415

rsmith31415 Apr 15, 2015

Contributor

@abreslow No problem. It would be nice to open an issue to fix that.

@moble By the way, did you open an issue in the matplotlib repository for your original problem?

@minrk Can you close this issue? Now we have a couple of reports, but none of them are fixable in this repository.

Contributor

rsmith31415 commented Apr 15, 2015

@abreslow No problem. It would be nice to open an issue to fix that.

@moble By the way, did you open an issue in the matplotlib repository for your original problem?

@minrk Can you close this issue? Now we have a couple of reports, but none of them are fixable in this repository.

@minrk minrk closed this Apr 15, 2015

@minrk

This comment has been minimized.

Show comment
Hide comment
@minrk

minrk Apr 15, 2015

Member

Thanks, folks.

Member

minrk commented Apr 15, 2015

Thanks, folks.

@tacaswell

This comment has been minimized.

Show comment
Hide comment
@tacaswell

tacaswell Apr 28, 2015

Contributor

@abreslow The issue you are seeing with clipping is a bug is librsvg rendering incorrectly, not in mpl emitting buggy svg. There is no constraint that clip paths must appear in the document before they are used. See much longer response at matplotlib/matplotlib#4341

Contributor

tacaswell commented Apr 28, 2015

@abreslow The issue you are seeing with clipping is a bug is librsvg rendering incorrectly, not in mpl emitting buggy svg. There is no constraint that clip paths must appear in the document before they are used. See much longer response at matplotlib/matplotlib#4341

tacaswell added a commit to tacaswell/matplotlib that referenced this issue Apr 28, 2015

BUG : fix svg corner case
Under certain conditions the ``id`` of the `clipPath` node emitted by
the svg writer will be the same for multiple files.  If both svg
fragments are embedded in the same document, then one of them is
removed, the clipping of the remaining fragment can become inconsistent.

See ipython/ipython#8133

Closes #4349
@tacaswell

This comment has been minimized.

Show comment
Hide comment
@tacaswell

tacaswell Apr 28, 2015

Contributor

@abreslow Please see matplotlib/matplotlib#4388 and see if that fixes your problem.

Contributor

tacaswell commented Apr 28, 2015

@abreslow Please see matplotlib/matplotlib#4388 and see if that fixes your problem.

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