Sep-28-2016, 02:07 AM
I would like to plot 2 curves and, in the legend, have a unique image for each curve and the corresponding curve color to show which it belongs to. I cannot figure out how to replace the text "Curve 1" or "Curve 2" with a sample of the actual curve, as you would usually see in the place of the monkey/giraffe in my case.
I don't have a great grasp on the handler, but I have enough to create the following code. See the attached image for clarification. To reproduce, you can download a monkey and giraffe png (monkey.png and giraffe.png) into the same directory you run the code in.
So instead of the legend showing:
image1 "curve 1" (where "Curve 1 is the actual text"
image2 "curve 2"
I would like:
image1 curve1 (where curve1 is a segment representing curve 1 (green line)
image2 curve2
I appreciate any help you can offer!
I don't have a great grasp on the handler, but I have enough to create the following code. See the attached image for clarification. To reproduce, you can download a monkey and giraffe png (monkey.png and giraffe.png) into the same directory you run the code in.
So instead of the legend showing:
image1 "curve 1" (where "Curve 1 is the actual text"
image2 "curve 2"
I would like:
image1 curve1 (where curve1 is a segment representing curve 1 (green line)
image2 curve2
I appreciate any help you can offer!
import os from matplotlib.transforms import TransformedBbox from matplotlib.image import BboxImage from matplotlib.legend_handler import HandlerBase from matplotlib._png import read_png from matplotlib.cbook import get_sample_data from matplotlib.transforms import Bbox import numpy as np import matplotlib.pyplot as plt import matplotlib matplotlib.rc('text', usetex = True) class ImageHandler(HandlerBase): def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans): # enlarge the image by these margins sx, sy = self.image_stretch # create a bounding box to house the image bb = Bbox.from_bounds(xdescent - sx, ydescent - sy, width + sx, height + sy) tbb = TransformedBbox(bb, trans) image = BboxImage(tbb) image.set_data(self.image_data) self.update_prop(image, orig_handle, legend) return [image] def set_image(self, image_path, image_stretch=(0, 0)): if not os.path.exists(image_path): #sample = get_sample_data("grace_hopper.png", asfileobj=False) sample = "monkey.png" self.image_data = read_png(sample) else: self.image_data = read_png(image_path) self.image_stretch = image_stretch class ImageHandler2(HandlerBase): def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans): # enlarge the image by these margins sx, sy = self.image_stretch # create a bounding box to house the image bb = Bbox.from_bounds(xdescent - sx, ydescent - sy, width + sx, height + sy) tbb = TransformedBbox(bb, trans) image = BboxImage(tbb) image.set_data(self.image_data) self.update_prop(image, orig_handle, legend) return [image] def set_image(self, image_path, image_stretch=(0, 0)): if not os.path.exists(image_path): #sample = get_sample_data("grace_hopper.png", asfileobj=False) sample = "giraffe.png" self.image_data = read_png(sample) else: self.image_data = read_png(image_path) self.image_stretch = image_stretch lw = 1.5; # LineWidth # Random curve d1 = np.linspace(25,3500); h1 = 2.020 * d1 **(0.449); h2 = 2.8 * d1 **(0.467); plt.figure() s, = plt.plot(d1,h1,'g',linewidth=lw) s2, = plt.plot(d1,h2,'b',linewidth=lw) # setup the handler instance for the scattered data custom_handler = ImageHandler() custom_handler.set_image("[PATH TO IMAGE]", image_stretch=(0, 20)) # this is for grace hopper custom_handler2 = ImageHandler2() custom_handler2.set_image("[PATH TO IMAGE]", image_stretch=(0, 20)) # this is for grace hopper # add the legend for the scattered data, mapping the # scattered points to the custom handler plt.legend([s, s2], ['Curve 1', 'Curve 2'], handler_map={s: custom_handler, s2: custom_handler2}, labelspacing=2, frameon=False, loc=2) plt.show()