Python PIL | ImageDraw.Draw.rectangle ()

Python Methods and Functions | rectangle

ImageDraw.Draw.rectangle() Draws a rectangle.

Syntax: PIL.ImageDraw. Draw.rectangle (xy, fill = None, outline = None)

xy - Four points to define the bounding box ... Sequence of either [(x0, y0), (x1, y1)] or [x0, y0, x1, y1]. The second point is just outside the drawn rectangle.
outline - Color to use for the outline.
fill - Color to use for the fill.

Returns: An Image object in rectangle shape.


# import image object from PIL

import math

from PIL import Image, ImageDraw


w, h = 220 , 190

shape = [( 40 , 40 ), (w - 10 , h - 10 )]

# create a new Image object

img = ( "RGB" , (w, h))

# create rectangular image

img1 = ImageDraw.Draw (img) 

img1.rectangle (shape, fill = "# ffff 33 " , outline = " red " ) ()


Another example: here we use a different fill color.


# import image object from PIL

import math

from PIL import Image, ImageDraw


w, h = 220 , 190

shape = [( 40 , 40 ), (w - 10 , h - 10 )]

# create a new Image

img = ( "RGB" , (w, h))

# create rectangle

img1 = ImageDraw.Draw (img) 

img1.rectangle (shape, fill = "# 800080" , outline = "green" ) ()


Python PIL | ImageDraw.Draw.rectangle (): StackOverflow Questions

matplotlib: how to draw a rectangle on image

How to draw a rectangle on an image, like this: enter image description here

import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
im = np.array("dog.png"), dtype=np.uint8)

I don"t know how to proceed.

Answer #1

Placing the legend (bbox_to_anchor)

A legend is positioned inside the bounding box of the axes using the loc argument to plt.legend.
E.g. loc="upper right" places the legend in the upper right corner of the bounding box, which by default extents from (0,0) to (1,1) in axes coordinates (or in bounding box notation (x0,y0, width, height)=(0,0,1,1)).

To place the legend outside of the axes bounding box, one may specify a tuple (x0,y0) of axes coordinates of the lower left corner of the legend.


A more versatile approach is to manually specify the bounding box into which the legend should be placed, using the bbox_to_anchor argument. One can restrict oneself to supply only the (x0, y0) part of the bbox. This creates a zero span box, out of which the legend will expand in the direction given by the loc argument. E.g.

plt.legend(bbox_to_anchor=(1.04,1), loc="upper left")

places the legend outside the axes, such that the upper left corner of the legend is at position (1.04,1) in axes coordinates.

Further examples are given below, where additionally the interplay between different arguments like mode and ncols are shown.

enter image description here

l1 = plt.legend(bbox_to_anchor=(1.04,1), borderaxespad=0)
l2 = plt.legend(bbox_to_anchor=(1.04,0), loc="lower left", borderaxespad=0)
l3 = plt.legend(bbox_to_anchor=(1.04,0.5), loc="center left", borderaxespad=0)
l4 = plt.legend(bbox_to_anchor=(0,1.02,1,0.2), loc="lower left",
                mode="expand", borderaxespad=0, ncol=3)
l5 = plt.legend(bbox_to_anchor=(1,0), loc="lower right", 
                bbox_transform=fig.transFigure, ncol=3)
l6 = plt.legend(bbox_to_anchor=(0.4,0.8), loc="upper right")

Details about how to interpret the 4-tuple argument to bbox_to_anchor, as in l4, can be found in this question. The mode="expand" expands the legend horizontally inside the bounding box given by the 4-tuple. For a vertically expanded legend, see this question.

Sometimes it may be useful to specify the bounding box in figure coordinates instead of axes coordinates. This is shown in the example l5 from above, where the bbox_transform argument is used to put the legend in the lower left corner of the figure.


Having placed the legend outside the axes often leads to the undesired situation that it is completely or partially outside the figure canvas.

Solutions to this problem are:

  • Adjust the subplot parameters
    One can adjust the subplot parameters such, that the axes take less space inside the figure (and thereby leave more space to the legend) by using plt.subplots_adjust. E.g.


leaves 30% space on the right-hand side of the figure, where one could place the legend.

  • Tight layout
    Using plt.tight_layout Allows to automatically adjust the subplot parameters such that the elements in the figure sit tight against the figure edges. Unfortunately, the legend is not taken into account in this automatism, but we can supply a rectangle box that the whole subplots area (including labels) will fit into.

  • Saving the figure with bbox_inches = "tight"
    The argument bbox_inches = "tight" to plt.savefig can be used to save the figure such that all artist on the canvas (including the legend) are fit into the saved area. If needed, the figure size is automatically adjusted.

      plt.savefig("output.png", bbox_inches="tight")
  • automatically adjusting the subplot params
    A way to automatically adjust the subplot position such that the legend fits inside the canvas without changing the figure size can be found in this answer: Creating figure with exact size and no padding (and legend outside the axes)

Comparison between the cases discussed above:

enter image description here


A figure legend

One may use a legend to the figure instead of the axes, matplotlib.figure.Figure.legend. This has become especially useful for matplotlib version >=2.1, where no special arguments are needed


to create a legend for all artists in the different axes of the figure. The legend is placed using the loc argument, similar to how it is placed inside an axes, but in reference to the whole figure - hence it will be outside the axes somewhat automatically. What remains is to adjust the subplots such that there is no overlap between the legend and the axes. Here the point "Adjust the subplot parameters" from above will be helpful. An example:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0,2*np.pi)
colors=["#7aa0c4","#ca82e1" ,"#8bcd50","#e18882"]
fig, axes = plt.subplots(ncols=2)
for i in range(4):
    axes[i//2].plot(x,np.sin(x+i), color=colors[i],label="y=sin(x+{})".format(i))


enter image description here

Legend inside dedicated subplot axes

An alternative to using bbox_to_anchor would be to place the legend in its dedicated subplot axes (lax). Since the legend subplot should be smaller than the plot, we may use gridspec_kw={"width_ratios":[4,1]} at axes creation. We can hide the axes lax.axis("off") but still put a legend in. The legend handles and labels need to obtained from the real plot via h,l = ax.get_legend_handles_labels(), and can then be supplied to the legend in the lax subplot, lax.legend(h,l). A complete example is below.

import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = 6,2

fig, (ax,lax) = plt.subplots(ncols=2, gridspec_kw={"width_ratios":[4,1]})
ax.plot(x,y, label="y=sin(x)")

h,l = ax.get_legend_handles_labels()
lax.legend(h,l, borderaxespad=0)


This produces a plot, which is visually pretty similar to the plot from above:

enter image description here

We could also use the first axes to place the legend, but use the bbox_transform of the legend axes,

ax.legend(bbox_to_anchor=(0,0,1,1), bbox_transform=lax.transAxes)

In this approach, we do not need to obtain the legend handles externally, but we need to specify the bbox_to_anchor argument.

Further reading and notes:

  • Consider the matplotlib legend guide with some examples of other stuff you want to do with legends.
  • Some example code for placing legends for pie charts may directly be found in answer to this question: Python - Legend overlaps with the pie chart
  • The loc argument can take numbers instead of strings, which make calls shorter, however, they are not very intuitively mapped to each other. Here is the mapping for reference:

enter image description here

Answer #2

You can add a Rectangle patch to the matplotlib Axes.

For example (using the image from the tutorial here):

import matplotlib.pyplot as plt
import matplotlib.patches as patches
from PIL import Image

im ="stinkbug.png")

# Create figure and axes
fig, ax = plt.subplots()

# Display the image

# Create a Rectangle patch
rect = patches.Rectangle((50, 100), 40, 30, linewidth=1, edgecolor="r", facecolor="none")

# Add the patch to the Axes

enter image description here

Answer #3

I"m trying to understand super()

The reason we use super is so that child classes that may be using cooperative multiple inheritance will call the correct next parent class function in the Method Resolution Order (MRO).

In Python 3, we can call it like this:

class ChildB(Base):
    def __init__(self):

In Python 2, we were required to call super like this with the defining class"s name and self, but we"ll avoid this from now on because it"s redundant, slower (due to the name lookups), and more verbose (so update your Python if you haven"t already!):

        super(ChildB, self).__init__()

Without super, you are limited in your ability to use multiple inheritance because you hard-wire the next parent"s call:

        Base.__init__(self) # Avoid this.

I further explain below.

"What difference is there actually in this code?:"

class ChildA(Base):
    def __init__(self):

class ChildB(Base):
    def __init__(self):

The primary difference in this code is that in ChildB you get a layer of indirection in the __init__ with super, which uses the class in which it is defined to determine the next class"s __init__ to look up in the MRO.

I illustrate this difference in an answer at the canonical question, How to use "super" in Python?, which demonstrates dependency injection and cooperative multiple inheritance.

If Python didn"t have super

Here"s code that"s actually closely equivalent to super (how it"s implemented in C, minus some checking and fallback behavior, and translated to Python):

class ChildB(Base):
    def __init__(self):
        mro = type(self).mro()
        check_next = mro.index(ChildB) + 1 # next after *this* class.
        while check_next < len(mro):
            next_class = mro[check_next]
            if "__init__" in next_class.__dict__:
            check_next += 1

Written a little more like native Python:

class ChildB(Base):
    def __init__(self):
        mro = type(self).mro()
        for next_class in mro[mro.index(ChildB) + 1:]: # slice to end
            if hasattr(next_class, "__init__"):

If we didn"t have the super object, we"d have to write this manual code everywhere (or recreate it!) to ensure that we call the proper next method in the Method Resolution Order!

How does super do this in Python 3 without being told explicitly which class and instance from the method it was called from?

It gets the calling stack frame, and finds the class (implicitly stored as a local free variable, __class__, making the calling function a closure over the class) and the first argument to that function, which should be the instance or class that informs it which Method Resolution Order (MRO) to use.

Since it requires that first argument for the MRO, using super with static methods is impossible as they do not have access to the MRO of the class from which they are called.

Criticisms of other answers:

super() lets you avoid referring to the base class explicitly, which can be nice. . But the main advantage comes with multiple inheritance, where all sorts of fun stuff can happen. See the standard docs on super if you haven"t already.

It"s rather hand-wavey and doesn"t tell us much, but the point of super is not to avoid writing the parent class. The point is to ensure that the next method in line in the method resolution order (MRO) is called. This becomes important in multiple inheritance.

I"ll explain here.

class Base(object):
    def __init__(self):
        print("Base init"ed")

class ChildA(Base):
    def __init__(self):
        print("ChildA init"ed")

class ChildB(Base):
    def __init__(self):
        print("ChildB init"ed")

And let"s create a dependency that we want to be called after the Child:

class UserDependency(Base):
    def __init__(self):
        print("UserDependency init"ed")

Now remember, ChildB uses super, ChildA does not:

class UserA(ChildA, UserDependency):
    def __init__(self):
        print("UserA init"ed")

class UserB(ChildB, UserDependency):
    def __init__(self):
        print("UserB init"ed")

And UserA does not call the UserDependency method:

>>> UserA()
UserA init"ed
ChildA init"ed
Base init"ed
<__main__.UserA object at 0x0000000003403BA8>

But UserB does in-fact call UserDependency because ChildB invokes super:

>>> UserB()
UserB init"ed
ChildB init"ed
UserDependency init"ed
Base init"ed
<__main__.UserB object at 0x0000000003403438>

Criticism for another answer

In no circumstance should you do the following, which another answer suggests, as you"ll definitely get errors when you subclass ChildB:

super(self.__class__, self).__init__()  # DON"T DO THIS! EVER.

(That answer is not clever or particularly interesting, but in spite of direct criticism in the comments and over 17 downvotes, the answerer persisted in suggesting it until a kind editor fixed his problem.)

Explanation: Using self.__class__ as a substitute for the class name in super() will lead to recursion. super lets us look up the next parent in the MRO (see the first section of this answer) for child classes. If you tell super we"re in the child instance"s method, it will then lookup the next method in line (probably this one) resulting in recursion, probably causing a logical failure (in the answerer"s example, it does) or a RuntimeError when the recursion depth is exceeded.

>>> class Polygon(object):
...     def __init__(self, id):
... = id
>>> class Rectangle(Polygon):
...     def __init__(self, id, width, height):
...         super(self.__class__, self).__init__(id)
...         self.shape = (width, height)
>>> class Square(Rectangle):
...     pass
>>> Square("a", 10, 10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
TypeError: __init__() missing 2 required positional arguments: "width" and "height"

Python 3"s new super() calling method with no arguments fortunately allows us to sidestep this issue.

Answer #4

Well, I decided to workout myself on my question to solve above problem. What I wanted is to implement a simpl OCR using KNearest or SVM features in OpenCV. And below is what I did and how. ( it is just for learning how to use KNearest for simple OCR purposes).

1) My first question was about file that comes with OpenCV samples. I wanted to know what is inside that file.

It contains a letter, along with 16 features of that letter.

And this SOF helped me to find it. These 16 features are explained in the paperLetter Recognition Using Holland-Style Adaptive Classifiers. ( Although I didn"t understand some of the features at end)

2) Since I knew, without understanding all those features, it is difficult to do that method. I tried some other papers, but all were a little difficult for a beginner.

So I just decided to take all the pixel values as my features. (I was not worried about accuracy or performance, I just wanted it to work, at least with the least accuracy)

I took below image for my training data:

enter image description here

( I know the amount of training data is less. But, since all letters are of same font and size, I decided to try on this).

To prepare the data for training, I made a small code in OpenCV. It does following things:

  1. It loads the image.
  2. Selects the digits ( obviously by contour finding and applying constraints on area and height of letters to avoid false detections).
  3. Draws the bounding rectangle around one letter and wait for key press manually. This time we press the digit key ourselves corresponding to the letter in box.
  4. Once corresponding digit key is pressed, it resizes this box to 10x10 and saves 100 pixel values in an array (here, samples) and corresponding manually entered digit in another array(here, responses).
  5. Then save both the arrays in separate txt files.

At the end of manual classification of digits, all the digits in the train data( train.png) are labeled manually by ourselves, image will look like below:

enter image description here

Below is the code I used for above purpose ( of course, not so clean):

import sys

import numpy as np
import cv2

im = cv2.imread("pitrain.png")
im3 = im.copy()

gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(5,5),0)
thresh = cv2.adaptiveThreshold(blur,255,1,1,11,2)

#################      Now finding Contours         ###################

contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

samples =  np.empty((0,100))
responses = []
keys = [i for i in range(48,58)]

for cnt in contours:
    if cv2.contourArea(cnt)>50:
        [x,y,w,h] = cv2.boundingRect(cnt)

        if  h>28:
            roi = thresh[y:y+h,x:x+w]
            roismall = cv2.resize(roi,(10,10))
            key = cv2.waitKey(0)

            if key == 27:  # (escape to quit)
            elif key in keys:
                sample = roismall.reshape((1,100))
                samples = np.append(samples,sample,0)

responses = np.array(responses,np.float32)
responses = responses.reshape((responses.size,1))
print "training complete"


Now we enter in to training and testing part.

For testing part I used below image, which has same type of letters I used to train.

enter image description here

For training we do as follows:

  1. Load the txt files we already saved earlier
  2. create a instance of classifier we are using ( here, it is KNearest)
  3. Then we use KNearest.train function to train the data

For testing purposes, we do as follows:

  1. We load the image used for testing
  2. process the image as earlier and extract each digit using contour methods
  3. Draw bounding box for it, then resize to 10x10, and store its pixel values in an array as done earlier.
  4. Then we use KNearest.find_nearest() function to find the nearest item to the one we gave. ( If lucky, it recognises the correct digit.)

I included last two steps ( training and testing) in single code below:

import cv2
import numpy as np

#######   training part    ############### 
samples = np.loadtxt("",np.float32)
responses = np.loadtxt("",np.float32)
responses = responses.reshape((responses.size,1))

model = cv2.KNearest()

############################# testing part  #########################

im = cv2.imread("pi.png")
out = np.zeros(im.shape,np.uint8)
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray,255,1,1,11,2)

contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

for cnt in contours:
    if cv2.contourArea(cnt)>50:
        [x,y,w,h] = cv2.boundingRect(cnt)
        if  h>28:
            roi = thresh[y:y+h,x:x+w]
            roismall = cv2.resize(roi,(10,10))
            roismall = roismall.reshape((1,100))
            roismall = np.float32(roismall)
            retval, results, neigh_resp, dists = model.find_nearest(roismall, k = 1)
            string = str(int((results[0][0])))


And it worked, below is the result I got:

enter image description here

Here it worked with 100% accuracy. I assume this is because all the digits are of same kind and same size.

But any way, this is a good start to go for beginners ( I hope so).

Answer #5

The standard way to add vertical lines that will cover your entire plot window without you having to specify their actual height is plt.axvline

import matplotlib.pyplot as plt



xcoords = [0.22058956, 0.33088437, 2.20589566]
for xc in xcoords:

You can use many of the keywords available for other plot commands (e.g. color, linestyle, linewidth ...). You can pass in keyword arguments ymin and ymax if you like in axes corrdinates (e.g. ymin=0.25, ymax=0.75 will cover the middle half of the plot). There are corresponding functions for horizontal lines (axhline) and rectangles (axvspan).

Answer #6

If you"re just wanting (semi) contiguous regions, there"s already an easy implementation in Python: SciPy"s ndimage.morphology module. This is a fairly common image morphology operation.

Basically, you have 5 steps:

def find_paws(data, smooth_radius=5, threshold=0.0001):
    data = sp.ndimage.uniform_filter(data, smooth_radius)
    thresh = data > threshold
    filled = sp.ndimage.morphology.binary_fill_holes(thresh)
    coded_paws, num_paws = sp.ndimage.label(filled)
    data_slices = sp.ndimage.find_objects(coded_paws)
    return object_slices
  1. Blur the input data a bit to make sure the paws have a continuous footprint. (It would be more efficient to just use a larger kernel (the structure kwarg to the various scipy.ndimage.morphology functions) but this isn"t quite working properly for some reason...)

  2. Threshold the array so that you have a boolean array of places where the pressure is over some threshold value (i.e. thresh = data > value)

  3. Fill any internal holes, so that you have cleaner regions (filled = sp.ndimage.morphology.binary_fill_holes(thresh))

  4. Find the separate contiguous regions (coded_paws, num_paws = sp.ndimage.label(filled)). This returns an array with the regions coded by number (each region is a contiguous area of a unique integer (1 up to the number of paws) with zeros everywhere else)).

  5. Isolate the contiguous regions using data_slices = sp.ndimage.find_objects(coded_paws). This returns a list of tuples of slice objects, so you could get the region of the data for each paw with [data[x] for x in data_slices]. Instead, we"ll draw a rectangle based on these slices, which takes slightly more work.

The two animations below show your "Overlapping Paws" and "Grouped Paws" example data. This method seems to be working perfectly. (And for whatever it"s worth, this runs much more smoothly than the GIF images below on my machine, so the paw detection algorithm is fairly fast...)

Overlapping Paws Grouped Paws

Here"s a full example (now with much more detailed explanations). The vast majority of this is reading the input and making an animation. The actual paw detection is only 5 lines of code.

import numpy as np
import scipy as sp
import scipy.ndimage

import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle

def animate(input_filename):
    """Detects paws and animates the position and raw data of each frame
    in the input file"""
    # With matplotlib, it"s much, much faster to just update the properties
    # of a display object than it is to create a new one, so we"ll just update
    # the data and position of the same objects throughout this animation...

    infile = paw_file(input_filename)

    # Since we"re making an animation with matplotlib, we need 
    # ion() instead of show()...
    fig = plt.figure()
    ax = fig.add_subplot(111)

    # Make an image based on the first frame that we"ll update later
    # (The first frame is never actually displayed)
    im = ax.imshow([1])

    # Make 4 rectangles that we can later move to the position of each paw
    rects = [Rectangle((0,0), 1,1, fc="none", ec="red") for i in range(4)]
    [ax.add_patch(rect) for rect in rects]

    title = ax.set_title("Time 0.0 ms")

    # Process and display each frame
    for time, frame in infile:
        paw_slices = find_paws(frame)

        # Hide any rectangles that might be visible
        [rect.set_visible(False) for rect in rects]

        # Set the position and size of a rectangle for each paw and display it
        for slice, rect in zip(paw_slices, rects):
            dy, dx = slice
            rect.set_xy((dx.start, dy.start))
            rect.set_width(dx.stop - dx.start + 1)
            rect.set_height(dy.stop - dy.start + 1)

        # Update the image data and title of the plot
        title.set_text("Time %0.2f ms" % time)
        im.set_clim([frame.min(), frame.max()])

def find_paws(data, smooth_radius=5, threshold=0.0001):
    """Detects and isolates contiguous regions in the input array"""
    # Blur the input data a bit so the paws have a continous footprint 
    data = sp.ndimage.uniform_filter(data, smooth_radius)
    # Threshold the blurred data (this needs to be a bit > 0 due to the blur)
    thresh = data > threshold
    # Fill any interior holes in the paws to get cleaner regions...
    filled = sp.ndimage.morphology.binary_fill_holes(thresh)
    # Label each contiguous paw
    coded_paws, num_paws = sp.ndimage.label(filled)
    # Isolate the extent of each paw
    data_slices = sp.ndimage.find_objects(coded_paws)
    return data_slices

def paw_file(filename):
    """Returns a iterator that yields the time and data in each frame
    The infile is an ascii file of timesteps formatted similar to this:

    Frame 0 (0.00 ms)
    0.0 0.0 0.0
    0.0 0.0 0.0

    Frame 1 (0.53 ms)
    0.0 0.0 0.0
    0.0 0.0 0.0
    with open(filename) as infile:
        while True:
                time, data = read_frame(infile)
                yield time, data
            except StopIteration:

def read_frame(infile):
    """Reads a frame from the infile."""
    frame_header =
    time = float(frame_header[-2][1:])
    data = []
    while True:
        line =
        if line == []:
    return time, np.array(data, dtype=np.float)

if __name__ == "__main__":
    animate("Overlapping paws.bin")
    animate("Grouped up paws.bin")
    animate("Normal measurement.bin")

Update: As far as identifying which paw is in contact with the sensor at what times, the simplest solution is to just do the same analysis, but use all of the data at once. (i.e. stack the input into a 3D array, and work with it, instead of the individual time frames.) Because SciPy"s ndimage functions are meant to work with n-dimensional arrays, we don"t have to modify the original paw-finding function at all.

# This uses functions (and imports) in the previous code example!!
def paw_regions(infile):
    # Read in and stack all data together into a 3D array
    data, time = [], []
    for t, frame in paw_file(infile):
    data = np.dstack(data)
    time = np.asarray(time)

    # Find and label the paw impacts
    data_slices, coded_paws = find_paws(data, smooth_radius=4)

    # Sort by time of initial paw impact... This way we can determine which
    # paws are which relative to the first paw with a simple modulo 4.
    # (Assuming a 4-legged dog, where all 4 paws contacted the sensor)
    data_slices.sort(key=lambda dat_slice: dat_slice[2].start)

    # Plot up a simple analysis
    fig = plt.figure()
    ax1 = fig.add_subplot(2,1,1)
    annotate_paw_prints(time, data, data_slices, ax=ax1)
    ax2 = fig.add_subplot(2,1,2)
    plot_paw_impacts(time, data_slices, ax=ax2)

def plot_paw_impacts(time, data_slices, ax=None):
    if ax is None:
        ax = plt.gca()

    # Group impacts by paw...
    for i, dat_slice in enumerate(data_slices):
        dx, dy, dt = dat_slice
        paw = i%4 + 1
        # Draw a bar over the time interval where each paw is in contact
        ax.barh(bottom=paw, width=time[dt].ptp(), height=0.2, 
                left=time[dt].min(), align="center", color="red")
    ax.set_yticks(range(1, 5))
    ax.set_yticklabels(["Paw 1", "Paw 2", "Paw 3", "Paw 4"])
    ax.set_xlabel("Time (ms) Since Beginning of Experiment")
    ax.set_title("Periods of Paw Contact")

def annotate_paw_prints(time, data, data_slices, ax=None):
    if ax is None:
        ax = plt.gca()

    # Display all paw impacts (sum over time)

    # Annotate each impact with which paw it is
    # (Relative to the first paw to hit the sensor)
    x, y = [], []
    for i, region in enumerate(data_slices):
        dx, dy, dz = region
        # Get x,y center of slice...
        x0 = 0.5 * (dx.start + dx.stop)
        y0 = 0.5 * (dy.start + dy.stop)
        x.append(x0); y.append(y0)

        # Annotate the paw impacts         
        ax.annotate("Paw %i" % (i%4 +1), (x0, y0),  
            color="red", ha="center", va="bottom")

    # Plot line connecting paw impacts
    ax.plot(x,y, "-wo")
    ax.set_title("Order of Steps")

alt text

alt text

alt text

Answer #7

Matplotlib uses a dictionary from its module.

To print the names use:

# python2:

import matplotlib
for name, hex in matplotlib.colors.cnames.iteritems():
    print(name, hex)

# python3:

import matplotlib
for name, hex in matplotlib.colors.cnames.items():
    print(name, hex)

This is the complete dictionary:

cnames = {
"aliceblue":            "#F0F8FF",
"antiquewhite":         "#FAEBD7",
"aqua":                 "#00FFFF",
"aquamarine":           "#7FFFD4",
"azure":                "#F0FFFF",
"beige":                "#F5F5DC",
"bisque":               "#FFE4C4",
"black":                "#000000",
"blanchedalmond":       "#FFEBCD",
"blue":                 "#0000FF",
"blueviolet":           "#8A2BE2",
"brown":                "#A52A2A",
"burlywood":            "#DEB887",
"cadetblue":            "#5F9EA0",
"chartreuse":           "#7FFF00",
"chocolate":            "#D2691E",
"coral":                "#FF7F50",
"cornflowerblue":       "#6495ED",
"cornsilk":             "#FFF8DC",
"crimson":              "#DC143C",
"cyan":                 "#00FFFF",
"darkblue":             "#00008B",
"darkcyan":             "#008B8B",
"darkgoldenrod":        "#B8860B",
"darkgray":             "#A9A9A9",
"darkgreen":            "#006400",
"darkkhaki":            "#BDB76B",
"darkmagenta":          "#8B008B",
"darkolivegreen":       "#556B2F",
"darkorange":           "#FF8C00",
"darkorchid":           "#9932CC",
"darkred":              "#8B0000",
"darksalmon":           "#E9967A",
"darkseagreen":         "#8FBC8F",
"darkslateblue":        "#483D8B",
"darkslategray":        "#2F4F4F",
"darkturquoise":        "#00CED1",
"darkviolet":           "#9400D3",
"deeppink":             "#FF1493",
"deepskyblue":          "#00BFFF",
"dimgray":              "#696969",
"dodgerblue":           "#1E90FF",
"firebrick":            "#B22222",
"floralwhite":          "#FFFAF0",
"forestgreen":          "#228B22",
"fuchsia":              "#FF00FF",
"gainsboro":            "#DCDCDC",
"ghostwhite":           "#F8F8FF",
"gold":                 "#FFD700",
"goldenrod":            "#DAA520",
"gray":                 "#808080",
"green":                "#008000",
"greenyellow":          "#ADFF2F",
"honeydew":             "#F0FFF0",
"hotpink":              "#FF69B4",
"indianred":            "#CD5C5C",
"indigo":               "#4B0082",
"ivory":                "#FFFFF0",
"khaki":                "#F0E68C",
"lavender":             "#E6E6FA",
"lavenderblush":        "#FFF0F5",
"lawngreen":            "#7CFC00",
"lemonchiffon":         "#FFFACD",
"lightblue":            "#ADD8E6",
"lightcoral":           "#F08080",
"lightcyan":            "#E0FFFF",
"lightgoldenrodyellow": "#FAFAD2",
"lightgreen":           "#90EE90",
"lightgray":            "#D3D3D3",
"lightpink":            "#FFB6C1",
"lightsalmon":          "#FFA07A",
"lightseagreen":        "#20B2AA",
"lightskyblue":         "#87CEFA",
"lightslategray":       "#778899",
"lightsteelblue":       "#B0C4DE",
"lightyellow":          "#FFFFE0",
"lime":                 "#00FF00",
"limegreen":            "#32CD32",
"linen":                "#FAF0E6",
"magenta":              "#FF00FF",
"maroon":               "#800000",
"mediumaquamarine":     "#66CDAA",
"mediumblue":           "#0000CD",
"mediumorchid":         "#BA55D3",
"mediumpurple":         "#9370DB",
"mediumseagreen":       "#3CB371",
"mediumslateblue":      "#7B68EE",
"mediumspringgreen":    "#00FA9A",
"mediumturquoise":      "#48D1CC",
"mediumvioletred":      "#C71585",
"midnightblue":         "#191970",
"mintcream":            "#F5FFFA",
"mistyrose":            "#FFE4E1",
"moccasin":             "#FFE4B5",
"navajowhite":          "#FFDEAD",
"navy":                 "#000080",
"oldlace":              "#FDF5E6",
"olive":                "#808000",
"olivedrab":            "#6B8E23",
"orange":               "#FFA500",
"orangered":            "#FF4500",
"orchid":               "#DA70D6",
"palegoldenrod":        "#EEE8AA",
"palegreen":            "#98FB98",
"paleturquoise":        "#AFEEEE",
"palevioletred":        "#DB7093",
"papayawhip":           "#FFEFD5",
"peachpuff":            "#FFDAB9",
"peru":                 "#CD853F",
"pink":                 "#FFC0CB",
"plum":                 "#DDA0DD",
"powderblue":           "#B0E0E6",
"purple":               "#800080",
"red":                  "#FF0000",
"rosybrown":            "#BC8F8F",
"royalblue":            "#4169E1",
"saddlebrown":          "#8B4513",
"salmon":               "#FA8072",
"sandybrown":           "#FAA460",
"seagreen":             "#2E8B57",
"seashell":             "#FFF5EE",
"sienna":               "#A0522D",
"silver":               "#C0C0C0",
"skyblue":              "#87CEEB",
"slateblue":            "#6A5ACD",
"slategray":            "#708090",
"snow":                 "#FFFAFA",
"springgreen":          "#00FF7F",
"steelblue":            "#4682B4",
"tan":                  "#D2B48C",
"teal":                 "#008080",
"thistle":              "#D8BFD8",
"tomato":               "#FF6347",
"turquoise":            "#40E0D0",
"violet":               "#EE82EE",
"wheat":                "#F5DEB3",
"white":                "#FFFFFF",
"whitesmoke":           "#F5F5F5",
"yellow":               "#FFFF00",
"yellowgreen":          "#9ACD32"}

You could plot them like this:

import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib.colors as colors
import math

fig = plt.figure()
ax = fig.add_subplot(111)

ratio = 1.0 / 3.0
count = math.ceil(math.sqrt(len(colors.cnames)))
x_count = count * ratio
y_count = count / ratio
x = 0
y = 0
w = 1 / x_count
h = 1 / y_count

for c in colors.cnames:
    pos = (x / x_count, y / y_count)
    ax.add_patch(patches.Rectangle(pos, w, h, color=c))
    ax.annotate(c, xy=pos)
    if y >= y_count-1:
        x += 1
        y = 0
        y += 1

Answer #8

It"s been noted that in Python 3.0+ you can use


to make your call, which is concise and does not require you to reference the parent OR class names explicitly, which can be handy. I just want to add that for Python 2.7 or under, some people implement a name-insensitive behaviour by writing self.__class__ instead of the class name, i.e.

super(self.__class__, self).__init__()  # DON"T DO THIS!

HOWEVER, this breaks calls to super for any classes that inherit from your class, where self.__class__ could return a child class. For example:

class Polygon(object):
    def __init__(self, id): = id

class Rectangle(Polygon):
    def __init__(self, id, width, height):
        super(self.__class__, self).__init__(id)
        self.shape = (width, height)

class Square(Rectangle):

Here I have a class Square, which is a sub-class of Rectangle. Say I don"t want to write a separate constructor for Square because the constructor for Rectangle is good enough, but for whatever reason I want to implement a Square so I can reimplement some other method.

When I create a Square using mSquare = Square("a", 10,10), Python calls the constructor for Rectangle because I haven"t given Square its own constructor. However, in the constructor for Rectangle, the call super(self.__class__,self) is going to return the superclass of mSquare, so it calls the constructor for Rectangle again. This is how the infinite loop happens, as was mentioned by @S_C. In this case, when I run super(...).__init__() I am calling the constructor for Rectangle but since I give it no arguments, I will get an error.

Answer #9

From PEP 8 -- Style Guide for Python Code:

The preferred way of wrapping long lines is by using Python"s implied line continuation inside parentheses, brackets and braces. Long lines can be broken over multiple lines by wrapping expressions in parentheses. These should be used in preference to using a backslash for line continuation.

Backslashes may still be appropriate at times. For example, long, multiple with-statements cannot use implicit continuation, so backslashes are acceptable:

with open("/path/to/some/file/you/want/to/read") as file_1, 
        open("/path/to/some/file/being/written", "w") as file_2:

Another such case is with assert statements.

Make sure to indent the continued line appropriately. The preferred place to break around a binary operator is after the operator, not before it. Some examples:

class Rectangle(Blob):

    def __init__(self, width, height,
                 color="black", emphasis=None, highlight=0):
        if (width == 0 and height == 0 and
                color == "red" and emphasis == "strong" or
                highlight > 100):
            raise ValueError("sorry, you lose")
        if width == 0 and height == 0 and (color == "red" or
                                           emphasis is None):
            raise ValueError("I don"t think so -- values are %s, %s" %
                             (width, height))
        Blob.__init__(self, width, height,
                      color, emphasis, highlight)

PEP8 now recommends the opposite convention (for breaking at binary operations) used by mathematicians and their publishers to improve readability.

Donald Knuth"s style of breaking before a binary operator aligns operators vertically, thus reducing the eye"s workload when determining which items are added and subtracted.

From PEP8: Should a line break before or after a binary operator?:

Donald Knuth explains the traditional rule in his Computers and Typesetting series: "Although formulas within a paragraph always break after binary operations and relations, displayed formulas always break before binary operations"[3].

Following the tradition from mathematics usually results in more readable code:

# Yes: easy to match operators with operands
income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends)
          - ira_deduction
          - student_loan_interest)

In Python code, it is permissible to break before or after a binary operator, as long as the convention is consistent locally. For new code Knuth"s style is suggested.

[3]: Donald Knuth"s The TeXBook, pages 195 and 196

Answer #10

It sounds like you want axvspan, rather than one of the fill between functions. The differences is that axvspan (and axhspan) will fill up the entire y (or x) extent of the plot regardless of how you zoom.

For example, let"s use axvspan to highlight the x-region between 8 and 14:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.axvspan(8, 14, alpha=0.5, color="red")

enter image description here

You could use fill_betweenx to do this, but the extents (both x and y) of the rectangle would be in data coordinates. With axvspan, the y-extents of the rectangle default to 0 and 1 and are in axes coordinates (in other words, percentages of the height of the plot).

To illustrate this, let"s make the rectangle extend from 10% to 90% of the height (instead of taking up the full extent). Try zooming or panning, and notice that the y-extents say fixed in display space, while the x-extents move with the zoom/pan:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.axvspan(8, 14, ymin=0.1, ymax=0.9, alpha=0.5, color="red")

enter image description here