Python Forum
Unique Legend Image and Line - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Unique Legend Image and Line (/thread-175.html)



Unique Legend Image and Line - nettesheim2 - Sep-28-2016

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!

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()



RE: Unique Legend Image and Line - Exponential_Sinusoid - Sep-30-2016

To be clear, you want to use the plotted function as the thumbnail for that plot alone? If I recall, with matplotlib, you should be able to generate an image of each plot and save them as the aforementioned "giraffe" and "monkey", no?