plot with polycollection disappears when polygons get too small












7














I'm using a PolyCollection to plot data of various sizes. Sometimes the polygons are very small. If they are too small, they don't get plotted at all. I would expect the outline at least to show up so you'd have an idea that some data is there. Is there a a setting to control this?



Here's some code to reproduce the problem, as well as the output image:



import matplotlib.pyplot as plt
from matplotlib.collections import PolyCollection
from matplotlib import colors

fig = plt.figure()
ax = fig.add_subplot(111)
verts =

edge_col = colors.colorConverter.to_rgb('lime')
face_col = [(2.0 + val) / 3.0 for val in edge_col] # a little lighter

for i in range(10):
w = 0.5 * 10**(-i)
xs = [i - w, i - w, i + w, i - w]
ys = [-w, w, 0, -w]

verts.append(list(zip(xs, ys)))

ax.set_xlim(-1, 11)
ax.set_ylim(-2, 2)

ax.add_collection(PolyCollection(verts, lw=3, alpha=0.5, edgecolor=edge_col, facecolor=face_col))

plt.savefig('out.png')


out



Notice that only six polygons are visible, whereas there should be ten.



Edit: I understand I could zoom in to see the others, but I was hoping to see a dot or the outline or something without doing this.



Edit 2: Here's a way to get the desired effect, by plotting the faces using a PolyCollection and then the edges using a series of Line2D plots with markers, based on Patol75's answer. My application is a matplotlib animation with lots of polygons, so I'd prefer to avoid Line2D for efficiency, and it would be cleaner if I didn't need to plot things twice, so I'm still hoping for a better answer.



ax.add_collection(PolyCollection(verts, lw=3, alpha=0.5, edgecolor=None, facecolor=face_col, zorder=1))

for pts in verts:
ax.add_line(Line2D([pt[0] for pt in pts], [pt[1] for pt in pts], lw=3, alpha=0.5, color=edge_col,
marker='.', ms=1, mec=edge_col, solid_capstyle='projecting', zorder=2))


out_line2d










share|improve this question





























    7














    I'm using a PolyCollection to plot data of various sizes. Sometimes the polygons are very small. If they are too small, they don't get plotted at all. I would expect the outline at least to show up so you'd have an idea that some data is there. Is there a a setting to control this?



    Here's some code to reproduce the problem, as well as the output image:



    import matplotlib.pyplot as plt
    from matplotlib.collections import PolyCollection
    from matplotlib import colors

    fig = plt.figure()
    ax = fig.add_subplot(111)
    verts =

    edge_col = colors.colorConverter.to_rgb('lime')
    face_col = [(2.0 + val) / 3.0 for val in edge_col] # a little lighter

    for i in range(10):
    w = 0.5 * 10**(-i)
    xs = [i - w, i - w, i + w, i - w]
    ys = [-w, w, 0, -w]

    verts.append(list(zip(xs, ys)))

    ax.set_xlim(-1, 11)
    ax.set_ylim(-2, 2)

    ax.add_collection(PolyCollection(verts, lw=3, alpha=0.5, edgecolor=edge_col, facecolor=face_col))

    plt.savefig('out.png')


    out



    Notice that only six polygons are visible, whereas there should be ten.



    Edit: I understand I could zoom in to see the others, but I was hoping to see a dot or the outline or something without doing this.



    Edit 2: Here's a way to get the desired effect, by plotting the faces using a PolyCollection and then the edges using a series of Line2D plots with markers, based on Patol75's answer. My application is a matplotlib animation with lots of polygons, so I'd prefer to avoid Line2D for efficiency, and it would be cleaner if I didn't need to plot things twice, so I'm still hoping for a better answer.



    ax.add_collection(PolyCollection(verts, lw=3, alpha=0.5, edgecolor=None, facecolor=face_col, zorder=1))

    for pts in verts:
    ax.add_line(Line2D([pt[0] for pt in pts], [pt[1] for pt in pts], lw=3, alpha=0.5, color=edge_col,
    marker='.', ms=1, mec=edge_col, solid_capstyle='projecting', zorder=2))


    out_line2d










    share|improve this question



























      7












      7








      7







      I'm using a PolyCollection to plot data of various sizes. Sometimes the polygons are very small. If they are too small, they don't get plotted at all. I would expect the outline at least to show up so you'd have an idea that some data is there. Is there a a setting to control this?



      Here's some code to reproduce the problem, as well as the output image:



      import matplotlib.pyplot as plt
      from matplotlib.collections import PolyCollection
      from matplotlib import colors

      fig = plt.figure()
      ax = fig.add_subplot(111)
      verts =

      edge_col = colors.colorConverter.to_rgb('lime')
      face_col = [(2.0 + val) / 3.0 for val in edge_col] # a little lighter

      for i in range(10):
      w = 0.5 * 10**(-i)
      xs = [i - w, i - w, i + w, i - w]
      ys = [-w, w, 0, -w]

      verts.append(list(zip(xs, ys)))

      ax.set_xlim(-1, 11)
      ax.set_ylim(-2, 2)

      ax.add_collection(PolyCollection(verts, lw=3, alpha=0.5, edgecolor=edge_col, facecolor=face_col))

      plt.savefig('out.png')


      out



      Notice that only six polygons are visible, whereas there should be ten.



      Edit: I understand I could zoom in to see the others, but I was hoping to see a dot or the outline or something without doing this.



      Edit 2: Here's a way to get the desired effect, by plotting the faces using a PolyCollection and then the edges using a series of Line2D plots with markers, based on Patol75's answer. My application is a matplotlib animation with lots of polygons, so I'd prefer to avoid Line2D for efficiency, and it would be cleaner if I didn't need to plot things twice, so I'm still hoping for a better answer.



      ax.add_collection(PolyCollection(verts, lw=3, alpha=0.5, edgecolor=None, facecolor=face_col, zorder=1))

      for pts in verts:
      ax.add_line(Line2D([pt[0] for pt in pts], [pt[1] for pt in pts], lw=3, alpha=0.5, color=edge_col,
      marker='.', ms=1, mec=edge_col, solid_capstyle='projecting', zorder=2))


      out_line2d










      share|improve this question















      I'm using a PolyCollection to plot data of various sizes. Sometimes the polygons are very small. If they are too small, they don't get plotted at all. I would expect the outline at least to show up so you'd have an idea that some data is there. Is there a a setting to control this?



      Here's some code to reproduce the problem, as well as the output image:



      import matplotlib.pyplot as plt
      from matplotlib.collections import PolyCollection
      from matplotlib import colors

      fig = plt.figure()
      ax = fig.add_subplot(111)
      verts =

      edge_col = colors.colorConverter.to_rgb('lime')
      face_col = [(2.0 + val) / 3.0 for val in edge_col] # a little lighter

      for i in range(10):
      w = 0.5 * 10**(-i)
      xs = [i - w, i - w, i + w, i - w]
      ys = [-w, w, 0, -w]

      verts.append(list(zip(xs, ys)))

      ax.set_xlim(-1, 11)
      ax.set_ylim(-2, 2)

      ax.add_collection(PolyCollection(verts, lw=3, alpha=0.5, edgecolor=edge_col, facecolor=face_col))

      plt.savefig('out.png')


      out



      Notice that only six polygons are visible, whereas there should be ten.



      Edit: I understand I could zoom in to see the others, but I was hoping to see a dot or the outline or something without doing this.



      Edit 2: Here's a way to get the desired effect, by plotting the faces using a PolyCollection and then the edges using a series of Line2D plots with markers, based on Patol75's answer. My application is a matplotlib animation with lots of polygons, so I'd prefer to avoid Line2D for efficiency, and it would be cleaner if I didn't need to plot things twice, so I'm still hoping for a better answer.



      ax.add_collection(PolyCollection(verts, lw=3, alpha=0.5, edgecolor=None, facecolor=face_col, zorder=1))

      for pts in verts:
      ax.add_line(Line2D([pt[0] for pt in pts], [pt[1] for pt in pts], lw=3, alpha=0.5, color=edge_col,
      marker='.', ms=1, mec=edge_col, solid_capstyle='projecting', zorder=2))


      out_line2d







      python matplotlib






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 21 at 15:58

























      asked Nov 12 at 19:31









      Stanley Bak

      292211




      292211
























          2 Answers
          2






          active

          oldest

          votes


















          2





          +50









          Zooming in your plotting window, you would notice that your two remaining polygons are being plotted. They are just too small for you to see them. One way to be convinced of this is to replace



          ax.set_xlim(-1, 6)
          ax.set_ylim(-2, 2)


          by



          ax.set_xlim(1e-1, 1e1)
          ax.set_ylim(1e-5, 1e0)
          ax.set_xscale('log')
          ax.set_yscale('log')
          ax.set_aspect('equal')


          Your five polygons are now visible, but on the downside the log scale restrains you to the positive side of the axes.
          enter image description here

          Now to propose an answer to your problem. If you keep a linear axis, as your polygons sizes span multiple orders of magnitude, you will not be able to see them all. What you can do is add an artist on your plot which specifies their location. This can be done with a marker, an arrow, etc... If we take the example of a marker, as you said, we only want to see this marker if we cannot see the polygon. The keyword zorder in the call to plot() allows to specify which artist should have the display priority on the figure. Please consider the example below.



          import matplotlib.pyplot as plt
          from matplotlib.collections import PolyCollection
          fig = plt.figure()
          ax = fig.add_subplot(111)
          verts =
          for i in range(5):
          w = 0.5 * 10**(-i)
          xs = [i - w, i - w, i + w, i + w, i - w]
          ys = [-w, w, w, -w, -w]
          ax.plot((xs[2] + xs[1]) / 2, (ys[1] + ys[0]) / 2, linestyle='none',
          marker='o', color='xkcd:crimson', markersize=1, zorder=-1)
          verts.append(list(zip(xs, ys)))
          ax.set_xlim(-1, 6)
          ax.set_ylim(-2, 2)
          poly = PolyCollection(verts, lw=5, edgecolor='black', facecolor='gray')
          ax.add_collection(poly)
          plt.show()


          which produces
          enter image description here

          You would notice that if you zoom on the last two dots in the matplotlib figure, you actually do not see the markers, but rather the polygons.






          share|improve this answer























          • It's true that if I zoom in I can see them, but in the real program will be plotting to a file and I won't know the polygon sizes ahead of time. I was hoping for the small ones I could see a dot on the plot, or the outline or something at least.
            – Stanley Bak
            Nov 13 at 15:48










          • Well you can always plot a marker at the center of your polygon for example.
            – Patol75
            Nov 13 at 21:55










          • Finding the center of generic polygons requires extra computation (center of the bounding box can be done by solving 4 linear programs, for example). Also, I would only want the markers to show up when the polygons are not there, otherwise there may be ugly cases where both are visible.
            – Stanley Bak
            Nov 15 at 16:26










          • I have updated my answer.
            – Patol75
            Nov 16 at 1:51










          • It's better. The real polygons have alpha values though, so things plotted underneath will show up. The idea of plotting twice once with polys and once with markers seems to work (I'm going to update the question). I'll hold off on awarding the bounty for a few days in case someone comes up with something cleaner / more efficient.
            – Stanley Bak
            Nov 16 at 20:40





















          1














          You may introduce some minimal unit minw, which is the smallest size a shape can have.



          import numpy as np
          import matplotlib.pyplot as plt
          from matplotlib.collections import PolyCollection
          from matplotlib import colors

          fig = plt.figure()
          ax = fig.add_subplot(111)
          verts =

          edge_col = colors.colorConverter.to_rgb('lime')
          face_col = [(2.0 + val) / 3.0 for val in edge_col] # a little lighter

          ax.set_xlim(-1, 11)
          ax.set_ylim(-2, 2)

          u = np.diff(np.array([ax.get_xlim(), ax.get_ylim()]), axis=1).min()
          px = np.max(fig.get_size_inches())*fig.dpi
          minw = u/px/2

          for i in range(10):
          w = 0.5 * 10**(-i)
          if w < minw:
          w = minw
          xs = [i - w, i - w, i + w, i - w]
          ys = [-w, w, 0, -w]

          verts.append(list(zip(xs, ys)))


          ax.add_collection(PolyCollection(verts, lw=3, alpha=0.5, edgecolor=edge_col, facecolor=face_col))

          plt.savefig('out.png')
          plt.show()


          enter image description here






          share|improve this answer





















          • The calculation using get_xlim, get_ylim, fig.get_size_inches, and fig.dpi is a neat way to do it, but it's a bit of a workaround for the problem. In the real application I'm doing an animation where the axis limits may change, so this wouldn't quite fit in that case. The shapes are also a bit more complicated, though you could compute a bounding box with the vertices and use that for the width.
            – Stanley Bak
            Nov 17 at 2:15












          • You could of course recompute the PolyCollection each time the axis limits change. (Not sure how often that'll be the case?)
            – ImportanceOfBeingErnest
            Nov 17 at 10:47











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53268881%2fplot-with-polycollection-disappears-when-polygons-get-too-small%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2





          +50









          Zooming in your plotting window, you would notice that your two remaining polygons are being plotted. They are just too small for you to see them. One way to be convinced of this is to replace



          ax.set_xlim(-1, 6)
          ax.set_ylim(-2, 2)


          by



          ax.set_xlim(1e-1, 1e1)
          ax.set_ylim(1e-5, 1e0)
          ax.set_xscale('log')
          ax.set_yscale('log')
          ax.set_aspect('equal')


          Your five polygons are now visible, but on the downside the log scale restrains you to the positive side of the axes.
          enter image description here

          Now to propose an answer to your problem. If you keep a linear axis, as your polygons sizes span multiple orders of magnitude, you will not be able to see them all. What you can do is add an artist on your plot which specifies their location. This can be done with a marker, an arrow, etc... If we take the example of a marker, as you said, we only want to see this marker if we cannot see the polygon. The keyword zorder in the call to plot() allows to specify which artist should have the display priority on the figure. Please consider the example below.



          import matplotlib.pyplot as plt
          from matplotlib.collections import PolyCollection
          fig = plt.figure()
          ax = fig.add_subplot(111)
          verts =
          for i in range(5):
          w = 0.5 * 10**(-i)
          xs = [i - w, i - w, i + w, i + w, i - w]
          ys = [-w, w, w, -w, -w]
          ax.plot((xs[2] + xs[1]) / 2, (ys[1] + ys[0]) / 2, linestyle='none',
          marker='o', color='xkcd:crimson', markersize=1, zorder=-1)
          verts.append(list(zip(xs, ys)))
          ax.set_xlim(-1, 6)
          ax.set_ylim(-2, 2)
          poly = PolyCollection(verts, lw=5, edgecolor='black', facecolor='gray')
          ax.add_collection(poly)
          plt.show()


          which produces
          enter image description here

          You would notice that if you zoom on the last two dots in the matplotlib figure, you actually do not see the markers, but rather the polygons.






          share|improve this answer























          • It's true that if I zoom in I can see them, but in the real program will be plotting to a file and I won't know the polygon sizes ahead of time. I was hoping for the small ones I could see a dot on the plot, or the outline or something at least.
            – Stanley Bak
            Nov 13 at 15:48










          • Well you can always plot a marker at the center of your polygon for example.
            – Patol75
            Nov 13 at 21:55










          • Finding the center of generic polygons requires extra computation (center of the bounding box can be done by solving 4 linear programs, for example). Also, I would only want the markers to show up when the polygons are not there, otherwise there may be ugly cases where both are visible.
            – Stanley Bak
            Nov 15 at 16:26










          • I have updated my answer.
            – Patol75
            Nov 16 at 1:51










          • It's better. The real polygons have alpha values though, so things plotted underneath will show up. The idea of plotting twice once with polys and once with markers seems to work (I'm going to update the question). I'll hold off on awarding the bounty for a few days in case someone comes up with something cleaner / more efficient.
            – Stanley Bak
            Nov 16 at 20:40


















          2





          +50









          Zooming in your plotting window, you would notice that your two remaining polygons are being plotted. They are just too small for you to see them. One way to be convinced of this is to replace



          ax.set_xlim(-1, 6)
          ax.set_ylim(-2, 2)


          by



          ax.set_xlim(1e-1, 1e1)
          ax.set_ylim(1e-5, 1e0)
          ax.set_xscale('log')
          ax.set_yscale('log')
          ax.set_aspect('equal')


          Your five polygons are now visible, but on the downside the log scale restrains you to the positive side of the axes.
          enter image description here

          Now to propose an answer to your problem. If you keep a linear axis, as your polygons sizes span multiple orders of magnitude, you will not be able to see them all. What you can do is add an artist on your plot which specifies their location. This can be done with a marker, an arrow, etc... If we take the example of a marker, as you said, we only want to see this marker if we cannot see the polygon. The keyword zorder in the call to plot() allows to specify which artist should have the display priority on the figure. Please consider the example below.



          import matplotlib.pyplot as plt
          from matplotlib.collections import PolyCollection
          fig = plt.figure()
          ax = fig.add_subplot(111)
          verts =
          for i in range(5):
          w = 0.5 * 10**(-i)
          xs = [i - w, i - w, i + w, i + w, i - w]
          ys = [-w, w, w, -w, -w]
          ax.plot((xs[2] + xs[1]) / 2, (ys[1] + ys[0]) / 2, linestyle='none',
          marker='o', color='xkcd:crimson', markersize=1, zorder=-1)
          verts.append(list(zip(xs, ys)))
          ax.set_xlim(-1, 6)
          ax.set_ylim(-2, 2)
          poly = PolyCollection(verts, lw=5, edgecolor='black', facecolor='gray')
          ax.add_collection(poly)
          plt.show()


          which produces
          enter image description here

          You would notice that if you zoom on the last two dots in the matplotlib figure, you actually do not see the markers, but rather the polygons.






          share|improve this answer























          • It's true that if I zoom in I can see them, but in the real program will be plotting to a file and I won't know the polygon sizes ahead of time. I was hoping for the small ones I could see a dot on the plot, or the outline or something at least.
            – Stanley Bak
            Nov 13 at 15:48










          • Well you can always plot a marker at the center of your polygon for example.
            – Patol75
            Nov 13 at 21:55










          • Finding the center of generic polygons requires extra computation (center of the bounding box can be done by solving 4 linear programs, for example). Also, I would only want the markers to show up when the polygons are not there, otherwise there may be ugly cases where both are visible.
            – Stanley Bak
            Nov 15 at 16:26










          • I have updated my answer.
            – Patol75
            Nov 16 at 1:51










          • It's better. The real polygons have alpha values though, so things plotted underneath will show up. The idea of plotting twice once with polys and once with markers seems to work (I'm going to update the question). I'll hold off on awarding the bounty for a few days in case someone comes up with something cleaner / more efficient.
            – Stanley Bak
            Nov 16 at 20:40
















          2





          +50







          2





          +50



          2




          +50




          Zooming in your plotting window, you would notice that your two remaining polygons are being plotted. They are just too small for you to see them. One way to be convinced of this is to replace



          ax.set_xlim(-1, 6)
          ax.set_ylim(-2, 2)


          by



          ax.set_xlim(1e-1, 1e1)
          ax.set_ylim(1e-5, 1e0)
          ax.set_xscale('log')
          ax.set_yscale('log')
          ax.set_aspect('equal')


          Your five polygons are now visible, but on the downside the log scale restrains you to the positive side of the axes.
          enter image description here

          Now to propose an answer to your problem. If you keep a linear axis, as your polygons sizes span multiple orders of magnitude, you will not be able to see them all. What you can do is add an artist on your plot which specifies their location. This can be done with a marker, an arrow, etc... If we take the example of a marker, as you said, we only want to see this marker if we cannot see the polygon. The keyword zorder in the call to plot() allows to specify which artist should have the display priority on the figure. Please consider the example below.



          import matplotlib.pyplot as plt
          from matplotlib.collections import PolyCollection
          fig = plt.figure()
          ax = fig.add_subplot(111)
          verts =
          for i in range(5):
          w = 0.5 * 10**(-i)
          xs = [i - w, i - w, i + w, i + w, i - w]
          ys = [-w, w, w, -w, -w]
          ax.plot((xs[2] + xs[1]) / 2, (ys[1] + ys[0]) / 2, linestyle='none',
          marker='o', color='xkcd:crimson', markersize=1, zorder=-1)
          verts.append(list(zip(xs, ys)))
          ax.set_xlim(-1, 6)
          ax.set_ylim(-2, 2)
          poly = PolyCollection(verts, lw=5, edgecolor='black', facecolor='gray')
          ax.add_collection(poly)
          plt.show()


          which produces
          enter image description here

          You would notice that if you zoom on the last two dots in the matplotlib figure, you actually do not see the markers, but rather the polygons.






          share|improve this answer














          Zooming in your plotting window, you would notice that your two remaining polygons are being plotted. They are just too small for you to see them. One way to be convinced of this is to replace



          ax.set_xlim(-1, 6)
          ax.set_ylim(-2, 2)


          by



          ax.set_xlim(1e-1, 1e1)
          ax.set_ylim(1e-5, 1e0)
          ax.set_xscale('log')
          ax.set_yscale('log')
          ax.set_aspect('equal')


          Your five polygons are now visible, but on the downside the log scale restrains you to the positive side of the axes.
          enter image description here

          Now to propose an answer to your problem. If you keep a linear axis, as your polygons sizes span multiple orders of magnitude, you will not be able to see them all. What you can do is add an artist on your plot which specifies their location. This can be done with a marker, an arrow, etc... If we take the example of a marker, as you said, we only want to see this marker if we cannot see the polygon. The keyword zorder in the call to plot() allows to specify which artist should have the display priority on the figure. Please consider the example below.



          import matplotlib.pyplot as plt
          from matplotlib.collections import PolyCollection
          fig = plt.figure()
          ax = fig.add_subplot(111)
          verts =
          for i in range(5):
          w = 0.5 * 10**(-i)
          xs = [i - w, i - w, i + w, i + w, i - w]
          ys = [-w, w, w, -w, -w]
          ax.plot((xs[2] + xs[1]) / 2, (ys[1] + ys[0]) / 2, linestyle='none',
          marker='o', color='xkcd:crimson', markersize=1, zorder=-1)
          verts.append(list(zip(xs, ys)))
          ax.set_xlim(-1, 6)
          ax.set_ylim(-2, 2)
          poly = PolyCollection(verts, lw=5, edgecolor='black', facecolor='gray')
          ax.add_collection(poly)
          plt.show()


          which produces
          enter image description here

          You would notice that if you zoom on the last two dots in the matplotlib figure, you actually do not see the markers, but rather the polygons.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 16 at 1:36

























          answered Nov 13 at 6:51









          Patol75

          6136




          6136












          • It's true that if I zoom in I can see them, but in the real program will be plotting to a file and I won't know the polygon sizes ahead of time. I was hoping for the small ones I could see a dot on the plot, or the outline or something at least.
            – Stanley Bak
            Nov 13 at 15:48










          • Well you can always plot a marker at the center of your polygon for example.
            – Patol75
            Nov 13 at 21:55










          • Finding the center of generic polygons requires extra computation (center of the bounding box can be done by solving 4 linear programs, for example). Also, I would only want the markers to show up when the polygons are not there, otherwise there may be ugly cases where both are visible.
            – Stanley Bak
            Nov 15 at 16:26










          • I have updated my answer.
            – Patol75
            Nov 16 at 1:51










          • It's better. The real polygons have alpha values though, so things plotted underneath will show up. The idea of plotting twice once with polys and once with markers seems to work (I'm going to update the question). I'll hold off on awarding the bounty for a few days in case someone comes up with something cleaner / more efficient.
            – Stanley Bak
            Nov 16 at 20:40




















          • It's true that if I zoom in I can see them, but in the real program will be plotting to a file and I won't know the polygon sizes ahead of time. I was hoping for the small ones I could see a dot on the plot, or the outline or something at least.
            – Stanley Bak
            Nov 13 at 15:48










          • Well you can always plot a marker at the center of your polygon for example.
            – Patol75
            Nov 13 at 21:55










          • Finding the center of generic polygons requires extra computation (center of the bounding box can be done by solving 4 linear programs, for example). Also, I would only want the markers to show up when the polygons are not there, otherwise there may be ugly cases where both are visible.
            – Stanley Bak
            Nov 15 at 16:26










          • I have updated my answer.
            – Patol75
            Nov 16 at 1:51










          • It's better. The real polygons have alpha values though, so things plotted underneath will show up. The idea of plotting twice once with polys and once with markers seems to work (I'm going to update the question). I'll hold off on awarding the bounty for a few days in case someone comes up with something cleaner / more efficient.
            – Stanley Bak
            Nov 16 at 20:40


















          It's true that if I zoom in I can see them, but in the real program will be plotting to a file and I won't know the polygon sizes ahead of time. I was hoping for the small ones I could see a dot on the plot, or the outline or something at least.
          – Stanley Bak
          Nov 13 at 15:48




          It's true that if I zoom in I can see them, but in the real program will be plotting to a file and I won't know the polygon sizes ahead of time. I was hoping for the small ones I could see a dot on the plot, or the outline or something at least.
          – Stanley Bak
          Nov 13 at 15:48












          Well you can always plot a marker at the center of your polygon for example.
          – Patol75
          Nov 13 at 21:55




          Well you can always plot a marker at the center of your polygon for example.
          – Patol75
          Nov 13 at 21:55












          Finding the center of generic polygons requires extra computation (center of the bounding box can be done by solving 4 linear programs, for example). Also, I would only want the markers to show up when the polygons are not there, otherwise there may be ugly cases where both are visible.
          – Stanley Bak
          Nov 15 at 16:26




          Finding the center of generic polygons requires extra computation (center of the bounding box can be done by solving 4 linear programs, for example). Also, I would only want the markers to show up when the polygons are not there, otherwise there may be ugly cases where both are visible.
          – Stanley Bak
          Nov 15 at 16:26












          I have updated my answer.
          – Patol75
          Nov 16 at 1:51




          I have updated my answer.
          – Patol75
          Nov 16 at 1:51












          It's better. The real polygons have alpha values though, so things plotted underneath will show up. The idea of plotting twice once with polys and once with markers seems to work (I'm going to update the question). I'll hold off on awarding the bounty for a few days in case someone comes up with something cleaner / more efficient.
          – Stanley Bak
          Nov 16 at 20:40






          It's better. The real polygons have alpha values though, so things plotted underneath will show up. The idea of plotting twice once with polys and once with markers seems to work (I'm going to update the question). I'll hold off on awarding the bounty for a few days in case someone comes up with something cleaner / more efficient.
          – Stanley Bak
          Nov 16 at 20:40















          1














          You may introduce some minimal unit minw, which is the smallest size a shape can have.



          import numpy as np
          import matplotlib.pyplot as plt
          from matplotlib.collections import PolyCollection
          from matplotlib import colors

          fig = plt.figure()
          ax = fig.add_subplot(111)
          verts =

          edge_col = colors.colorConverter.to_rgb('lime')
          face_col = [(2.0 + val) / 3.0 for val in edge_col] # a little lighter

          ax.set_xlim(-1, 11)
          ax.set_ylim(-2, 2)

          u = np.diff(np.array([ax.get_xlim(), ax.get_ylim()]), axis=1).min()
          px = np.max(fig.get_size_inches())*fig.dpi
          minw = u/px/2

          for i in range(10):
          w = 0.5 * 10**(-i)
          if w < minw:
          w = minw
          xs = [i - w, i - w, i + w, i - w]
          ys = [-w, w, 0, -w]

          verts.append(list(zip(xs, ys)))


          ax.add_collection(PolyCollection(verts, lw=3, alpha=0.5, edgecolor=edge_col, facecolor=face_col))

          plt.savefig('out.png')
          plt.show()


          enter image description here






          share|improve this answer





















          • The calculation using get_xlim, get_ylim, fig.get_size_inches, and fig.dpi is a neat way to do it, but it's a bit of a workaround for the problem. In the real application I'm doing an animation where the axis limits may change, so this wouldn't quite fit in that case. The shapes are also a bit more complicated, though you could compute a bounding box with the vertices and use that for the width.
            – Stanley Bak
            Nov 17 at 2:15












          • You could of course recompute the PolyCollection each time the axis limits change. (Not sure how often that'll be the case?)
            – ImportanceOfBeingErnest
            Nov 17 at 10:47
















          1














          You may introduce some minimal unit minw, which is the smallest size a shape can have.



          import numpy as np
          import matplotlib.pyplot as plt
          from matplotlib.collections import PolyCollection
          from matplotlib import colors

          fig = plt.figure()
          ax = fig.add_subplot(111)
          verts =

          edge_col = colors.colorConverter.to_rgb('lime')
          face_col = [(2.0 + val) / 3.0 for val in edge_col] # a little lighter

          ax.set_xlim(-1, 11)
          ax.set_ylim(-2, 2)

          u = np.diff(np.array([ax.get_xlim(), ax.get_ylim()]), axis=1).min()
          px = np.max(fig.get_size_inches())*fig.dpi
          minw = u/px/2

          for i in range(10):
          w = 0.5 * 10**(-i)
          if w < minw:
          w = minw
          xs = [i - w, i - w, i + w, i - w]
          ys = [-w, w, 0, -w]

          verts.append(list(zip(xs, ys)))


          ax.add_collection(PolyCollection(verts, lw=3, alpha=0.5, edgecolor=edge_col, facecolor=face_col))

          plt.savefig('out.png')
          plt.show()


          enter image description here






          share|improve this answer





















          • The calculation using get_xlim, get_ylim, fig.get_size_inches, and fig.dpi is a neat way to do it, but it's a bit of a workaround for the problem. In the real application I'm doing an animation where the axis limits may change, so this wouldn't quite fit in that case. The shapes are also a bit more complicated, though you could compute a bounding box with the vertices and use that for the width.
            – Stanley Bak
            Nov 17 at 2:15












          • You could of course recompute the PolyCollection each time the axis limits change. (Not sure how often that'll be the case?)
            – ImportanceOfBeingErnest
            Nov 17 at 10:47














          1












          1








          1






          You may introduce some minimal unit minw, which is the smallest size a shape can have.



          import numpy as np
          import matplotlib.pyplot as plt
          from matplotlib.collections import PolyCollection
          from matplotlib import colors

          fig = plt.figure()
          ax = fig.add_subplot(111)
          verts =

          edge_col = colors.colorConverter.to_rgb('lime')
          face_col = [(2.0 + val) / 3.0 for val in edge_col] # a little lighter

          ax.set_xlim(-1, 11)
          ax.set_ylim(-2, 2)

          u = np.diff(np.array([ax.get_xlim(), ax.get_ylim()]), axis=1).min()
          px = np.max(fig.get_size_inches())*fig.dpi
          minw = u/px/2

          for i in range(10):
          w = 0.5 * 10**(-i)
          if w < minw:
          w = minw
          xs = [i - w, i - w, i + w, i - w]
          ys = [-w, w, 0, -w]

          verts.append(list(zip(xs, ys)))


          ax.add_collection(PolyCollection(verts, lw=3, alpha=0.5, edgecolor=edge_col, facecolor=face_col))

          plt.savefig('out.png')
          plt.show()


          enter image description here






          share|improve this answer












          You may introduce some minimal unit minw, which is the smallest size a shape can have.



          import numpy as np
          import matplotlib.pyplot as plt
          from matplotlib.collections import PolyCollection
          from matplotlib import colors

          fig = plt.figure()
          ax = fig.add_subplot(111)
          verts =

          edge_col = colors.colorConverter.to_rgb('lime')
          face_col = [(2.0 + val) / 3.0 for val in edge_col] # a little lighter

          ax.set_xlim(-1, 11)
          ax.set_ylim(-2, 2)

          u = np.diff(np.array([ax.get_xlim(), ax.get_ylim()]), axis=1).min()
          px = np.max(fig.get_size_inches())*fig.dpi
          minw = u/px/2

          for i in range(10):
          w = 0.5 * 10**(-i)
          if w < minw:
          w = minw
          xs = [i - w, i - w, i + w, i - w]
          ys = [-w, w, 0, -w]

          verts.append(list(zip(xs, ys)))


          ax.add_collection(PolyCollection(verts, lw=3, alpha=0.5, edgecolor=edge_col, facecolor=face_col))

          plt.savefig('out.png')
          plt.show()


          enter image description here







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 17 at 1:39









          ImportanceOfBeingErnest

          125k10128204




          125k10128204












          • The calculation using get_xlim, get_ylim, fig.get_size_inches, and fig.dpi is a neat way to do it, but it's a bit of a workaround for the problem. In the real application I'm doing an animation where the axis limits may change, so this wouldn't quite fit in that case. The shapes are also a bit more complicated, though you could compute a bounding box with the vertices and use that for the width.
            – Stanley Bak
            Nov 17 at 2:15












          • You could of course recompute the PolyCollection each time the axis limits change. (Not sure how often that'll be the case?)
            – ImportanceOfBeingErnest
            Nov 17 at 10:47


















          • The calculation using get_xlim, get_ylim, fig.get_size_inches, and fig.dpi is a neat way to do it, but it's a bit of a workaround for the problem. In the real application I'm doing an animation where the axis limits may change, so this wouldn't quite fit in that case. The shapes are also a bit more complicated, though you could compute a bounding box with the vertices and use that for the width.
            – Stanley Bak
            Nov 17 at 2:15












          • You could of course recompute the PolyCollection each time the axis limits change. (Not sure how often that'll be the case?)
            – ImportanceOfBeingErnest
            Nov 17 at 10:47
















          The calculation using get_xlim, get_ylim, fig.get_size_inches, and fig.dpi is a neat way to do it, but it's a bit of a workaround for the problem. In the real application I'm doing an animation where the axis limits may change, so this wouldn't quite fit in that case. The shapes are also a bit more complicated, though you could compute a bounding box with the vertices and use that for the width.
          – Stanley Bak
          Nov 17 at 2:15






          The calculation using get_xlim, get_ylim, fig.get_size_inches, and fig.dpi is a neat way to do it, but it's a bit of a workaround for the problem. In the real application I'm doing an animation where the axis limits may change, so this wouldn't quite fit in that case. The shapes are also a bit more complicated, though you could compute a bounding box with the vertices and use that for the width.
          – Stanley Bak
          Nov 17 at 2:15














          You could of course recompute the PolyCollection each time the axis limits change. (Not sure how often that'll be the case?)
          – ImportanceOfBeingErnest
          Nov 17 at 10:47




          You could of course recompute the PolyCollection each time the axis limits change. (Not sure how often that'll be the case?)
          – ImportanceOfBeingErnest
          Nov 17 at 10:47


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53268881%2fplot-with-polycollection-disappears-when-polygons-get-too-small%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Xamarin.iOS Cant Deploy on Iphone

          Glorious Revolution

          Dulmage-Mendelsohn matrix decomposition in Python