plot with polycollection disappears when polygons get too small
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')
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))
python matplotlib
add a comment |
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')
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))
python matplotlib
add a comment |
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')
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))
python matplotlib
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')
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))
python matplotlib
python matplotlib
edited Nov 21 at 15:58
asked Nov 12 at 19:31
Stanley Bak
292211
292211
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
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.
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
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.
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
|
show 1 more comment
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()
The calculation usingget_xlim
,get_ylim
,fig.get_size_inches
, andfig.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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
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.
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
|
show 1 more comment
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.
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
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.
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
|
show 1 more comment
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.
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
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.
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.
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
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.
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
|
show 1 more comment
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
|
show 1 more comment
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()
The calculation usingget_xlim
,get_ylim
,fig.get_size_inches
, andfig.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
add a comment |
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()
The calculation usingget_xlim
,get_ylim
,fig.get_size_inches
, andfig.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
add a comment |
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()
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()
answered Nov 17 at 1:39
ImportanceOfBeingErnest
125k10128204
125k10128204
The calculation usingget_xlim
,get_ylim
,fig.get_size_inches
, andfig.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
add a comment |
The calculation usingget_xlim
,get_ylim
,fig.get_size_inches
, andfig.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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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