21

I would like to utilize customer markers in both scatter and line charts. How can I make custom marker out of a PNG file?

ImportanceOfBeingErnest
342k60 gold badges735 silver badges770 bronze badges
asked Feb 23, 2010 at 13:07
2

3 Answers 3

30

I don't believe matplotlib can customize markers like that. See here for the level of customization, which falls way short of what you need.

As an alternative, I've coded up this kludge which uses matplotlib.image to place images at the line point locations.

import matplotlib.pyplot as plt
from matplotlib import image
# constant
dpi = 72
path = 'smile.png'
# read in our png file
im = image.imread(path)
image_size = im.shape[1], im.shape[0]
fig = plt.figure(dpi=dpi)
ax = fig.add_subplot(111)
# plot our line with transparent markers, and markersize the size of our image
line, = ax.plot((1,2,3,4),(1,2,3,4),"bo",mfc="None",mec="None",markersize=image_size[0] * (dpi/ 96))
# we need to make the frame transparent so the image can be seen
# only in trunk can you put the image on top of the plot, see this link:
# http://www.mail-archive.com/[email protected]/msg14534.html
ax.patch.set_alpha(0)
ax.set_xlim((0,5))
ax.set_ylim((0,5))
# translate point positions to pixel positions
# figimage needs pixels not points
line._transform_path()
path, affine = line._transformed_path.get_transformed_points_and_affine()
path = affine.transform_path(path)
for pixelPoint in path.vertices:
 # place image at point, centering it
 fig.figimage(im,pixelPoint[0]-image_size[0]/2,pixelPoint[1]-image_size[1]/2,origin="upper")
plt.show()

Produces:

enter image description here

answered Feb 23, 2010 at 17:04
2
  • 4
    AttributeError: 'AxesSubplot' object has no attribute 'get_frame' Commented Nov 16, 2014 at 15:45
  • See answer by t gillespie for handling get_frame error Commented Feb 20, 2016 at 4:33
9

Following on from Mark's answer. I just thought I would add to this a bit because I tried to run this and it does what I want with the exception of actually displaying the icons on the graph. Maybe something has changed with matplotlib. It has been 4 years.

The line of code that reads:

ax.get_frame().set_alpha(0)

does not seem to work, however

ax.patch.set_alpha(0)

does work.

Synesso
39.2k35 gold badges144 silver badges213 bronze badges
answered Mar 20, 2015 at 6:28
0
9

The other answer may lead to problems when resizing the figure. Here is a different approach, positionning the images inside annotation boxes, which are anchored in data coordinates.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
path = "https://upload.wikimedia.org/wikipedia/commons/b/b5/Tango-example_icons.png"
image = plt.imread(path)[116:116+30, 236:236+30]
x = np.arange(10)
y = np.random.rand(10)
fig, ax = plt.subplots()
ax.plot(x,y)
def plot_images(x, y, image, ax=None):
 ax = ax or plt.gca()
 for xi, yi in zip(x,y):
 im = OffsetImage(image, zoom=72/ax.figure.dpi)
 im.image.axes = ax
 ab = AnnotationBbox(im, (xi,yi), frameon=False, pad=0.0,)
 ax.add_artist(ab)
plot_images(x, y, image, ax=ax)
plt.show()

enter image description here

answered Feb 12, 2020 at 17:14

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.