Sebastian
Sebastian

Reputation: 11

Matplotlib Custom Marker Path

I am trying to create custom markers in Matplotlib using the Path instance as documented here: https://matplotlib.org/api/markers_api.html#module-matplotlib.markers

import matplotlib.pyplot as plt
import matplotlib as mpl

x = [1, 2, 3, 4]
y = [1, 4, 9, 6]

custommarker = mpl.path.Path([[0,0],[1,1],[1,0]],[1,2,2])
plt.plot(1.5,0,marker=custommarker)

plt.plot(x, y, 'ro')
plt.subplots_adjust(bottom=0.15)
plt.show()

When I run the Code I get the error:

TypeError: 'Path' object does not support indexing

In mpl 1.3.x this was working but since mpl 2.x.x I get this error. Can anyone help me? Thanks a lot.

Upvotes: 0

Views: 1231

Answers (1)

OriolAbril
OriolAbril

Reputation: 8783

From the complete error message generated from your code, it could be seen that the error is in the function set_marker in the actual markers.py function. As noted by ImportanceOfBeingErnest in the comments, this is actually a bug that has already been fixed, but still not released (to date 12/04/2018), as can be seen in the current master version of markers.py.

The code raising the error is the following:

if (isinstance(marker, np.ndarray) and marker.ndim == 2 and
        marker.shape[1] == 2):
    self._marker_function = self._set_vertices
elif (isinstance(marker, Sized) and len(marker) in (2, 3) and
        marker[1] in (0, 1, 2, 3)):
    self._marker_function = self._set_tuple_marker

And it is not until some elif later that the check for isinstance(marker,Path) is performed.

One workaround is to trigger the first if, to avoid ending up executing marker[1]. This condition checks for numpy arrays with dimensions consitent with the vertices of a path object, and instead of passing the custommarker, pass its vertices:

plt.plot(1.5,0,marker=custommarker.vertices)

The other option is to avoid the second if using a different lenght for the marker, because only len(marker) in (2,3) will give errors:

custommarker = mpl.path.Path([(0,0),(1,1),(1,0),(1,0)],[1,2,2,79]) # Or a 0 as final code if instead o closing the line should stop there.

Both workarounds give the same result.

Upvotes: 1

Related Questions