Custom marker created from vertex list scales wrong #1980

vMeijin opened this Issue May 6, 2013 · 3 comments


None yet
4 participants

vMeijin commented May 6, 2013

I am new here and I dont know if this is the right place, but I found a slight misbehave, when creating a custom markerstyle. If you plot something, eg:

pyplot.plot([0,0], [1,1], markersize=5, marker=[[0,0], [0,1], [1, 1], [1,0]) # marker is a square with size 1

The marker has the same size as marker='s', but is not centered. If you use

pyplot.plot([0,0], [1,1], markersize=5, marker=[[-0.5,-0.5], [-0.5,0.5], [0.5,0.5]], [0.5,-0.5]) # still square of size 1

the resulting marker is centered but twice the size. The problem is the the function MarkerStyle._set_custom_marker in

def _set_custom_marker(self, path):
    verts = path.vertices
    rescale = max(np.max(np.abs(verts[:,0])), np.max(np.abs(verts[:,1])))
    self._transform = Affine2D().scale(1.0 / rescale)
    self._path = path

It rescales the given vertices, but considers only the max xy values, which results in twice. the size A solution could be to change the rescale factor to:

x, y = verts[:,0], verts[:,1]
rescale = max(abs(np.max(x) - np.min(x)), abs(np.max(y) - np.min(y)))


pelson commented May 8, 2013

Hi @vMeijin,

It doesn't seem to say it anywhere, but I think your marker should be in the range [-1, 1] - or at least, looking at your code, centred about 0 in both x and y. The nearest I could find to documentation was here. There is also an example in the gallery which makes use of this range (it creates a unit circle).

Does that answer your question?

If so, given what you now know, do you think the documentation could be improved? The documentation for this part of matplotlib can be found and we would really value any contribution to make it better.


vMeijin commented May 8, 2013

I tried it with markers in range [-1, 1]. They are still twice the size of the normal markers. The problem is this line

rescale = max(np.max(np.abs(verts[:,0])), np.max(np.abs(verts[:,1])))

It only considers the absolute max of the x/y (which would be 1 in this case) for rescale. Here is a small example which shows the difference:

from matplotlib import pyplot
import numpy
pyplot.plot([0, 1, 2], [0, 1, 2], marker="s", markersize=20)
pyplot.plot([0, 1, 2 ], [1, 2, 3], marker=numpy.array([[-1, -1], [-1, 1], [1, 1], [1, -1]]), markersize=20)

dmcdougall commented Jun 19, 2013

@vMeijin Here's the plot output of your example.


I'm in agreement with @vMeijin here. I think they should be the same size.

tacaswell added this to the v1.4.x milestone Aug 17, 2014

@cimarronm cimarronm added a commit to cimarronm/matplotlib that referenced this issue Aug 17, 2014

@cimarronm cimarronm BUG: Fixes custom path marker sizing for issue #1980 d2a8990

@cimarronm cimarronm added a commit to cimarronm/matplotlib that referenced this issue Aug 17, 2014

@cimarronm cimarronm BUG: Fixes custom path marker sizing for issue #1980 481314e

@tacaswell tacaswell added has_patch and removed needs_patch labels Aug 18, 2014

tacaswell closed this in 98d19db Aug 26, 2014

tbreloff referenced this issue in JuliaPlots/Plots.jl Mar 16, 2016


How to plot a partial annulus? #163

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