Skip to content

Instantly share code, notes, and snippets.

@neilpanchal
Created December 6, 2016 06:38
Show Gist options
  • Save neilpanchal/b1fd2c2f2f0bbb6e62529b6da8adf101 to your computer and use it in GitHub Desktop.
Save neilpanchal/b1fd2c2f2f0bbb6e62529b6da8adf101 to your computer and use it in GitHub Desktop.
==================================================
Getting Started With Matplotlib's OO Class Library
==================================================
Introduction
------------
For those people coming to Matplotlib without any prior experience
of MatLab and who are familiar with the basic concepts of
programming API's and classes, learning to use Matplotlib via the
class library is an excellent choice. The library is well put
together and works very intuitively once a few fundamentals are
grasped.
The advice from John Hunter, the original developer of the library
is 'don't be afraid to open up matplotlib/pylab.py to see how the
pylab interface forwards its calls to the OO layer.' That in
combination with the user's guide, the examples/embedding demos,
and the mailing lists, which are regularly read by many developers
are an excellent way to learn the class library.
Following is a brief introduction to using the class library,
developed as I came to grips with how to produce my first graphs.
Classes/Terms
-------------
FigureCanvas - is primarily a container class to hold the Figure
instance, an approach which enforces a rigid segregation between
the plot elements, and the drawing of those elements. It can be
loosely thought of as 'the place where the ink goes'.
Figure - a container for one or more Axes. It is possible to
create and manage an arbitrary number of figures using the Figure
class. Note also that a figure can have its own line, text and
patch elements, independent of any axes.
Axes - the rectangular area which holds the basic elements (Line2D,
Rectangle, Text, etc) that are generated by the Axes plotting
commands (e.g. the Axes plot, scatter, bar, hist methods). The Figure
methods add_axes and add_subplot are used to create and add an Axes
instance to the Figure. You should not instantiate an Axes instance
yourself, but rather use one of these helper methods.
Line - implemented in the Line2D class, can draw lines(!) with a
variety of styles (solid, dashed, dotted, etc), markers (location
indicators on the line - point, circle, triangle, diamond, etc) and
colours (k or #000000 - black, w or #FFFFFF - white, b or #000099 -
blue, etc)
Text - a class that handles storing and drawing of text in window
or data coordinates. The text can be coloured, rotated, aligned in
various ways relative to the origin point, and have font properties
(weight, style, etc) assigned to it.
Patch - a patch is a two dimensional shape with a separately
specifiable face and edge colour. Specialised patch classes include
circle, rectangle, regular polygon and more.
Ticks - the indicators of where on an axis a particular value
lies. Separate classes exist for the x and y axis ticks, (XTick,
YTick) and each are comprised of the primitive Line2D and Text
instances that make up the tick.
Artist - Everything that draws into a canvas derives from Artist
(Figure, Axes, Axis, Line2D, Rectangle, Text, and more). Some of
these are primitives (Line2D, Rectangle, Text, Circle, etc) in that
they do not contain any other Artists, some are simple composites,
e.g. XTick which is mad up of a couple of Line2D and Text instances
(upper and lower tick lines and labels), and some are complex, e.g.
and Axes or a Figure, which contain both composite and primitive
artists.
Techniques
----------
1. Setting up an agg backend canvas:
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
fig = Figure()
canvas = FigureCanvas(fig)
2. To set the size of the Figure, use the figsize keyword, which uses
inches as the units:
# this results in a 204x192 pixel png - if output at 100 dpi, using
# canvas.print_figure(.., dpi=100)
fig = Figure(figsize=(2.04,1.92))
canvas = FigureCanvas(fig)
3. To add a single subplot:
# The 111 specifies 1 row, 1 column on subplot #1
ax = fig.add_subplot(111)
4. To change the axes size and location on construction, e.g to fit
the labels in on a small graph:
ax = fig.add_axes([0.2,0.2,0.5,0.7])
An existing Axes position/location can be changed by calling
the set_position() method.
5. Adding a graph of some sort is as simple as calling the required
function on the axes instance:
p1 = ax.bar(...) or p1 = ax.plot(...)
6. Setting a label with extra small text:
ax.set_xlabel('Yrs', size='x-small')
7. Setting the graph title:
ax.set_title(A graph title', size='x-small')
8. To enable only the horizontal grid on the major ticks:
ax.grid(False)
ax.yaxis.grid(True, which='major')
9. To only have a left y-axis and a bottom x-axis:
# set the edgecolor and facecolor of the axes rectangle to be the same
frame = ax.axesPatch
frame.set_edgecolor(frame.get_facecolor())
# Specify a line in axes coords to represent the left and bottom axes.
bottom = Line2D([0, 1], [0, 0], transform=ax.transAxes)
left = Line2D([0, 0], [0, 1], transform=ax.transAxes)
ax.add_line(bottom)
ax.add_line(left)
10. To change the size of the tick labels :
labels = ax.get_xticklabels() + ax.get_yticklabels()
for label in labels:
label.set_size('x-small')
11. Removing the black rectangle around an individual bar graph
rectangle (by changing it to the bar colour) :
c = '#7FBFFF'
p1 = ax.bar(ind, values, width, color=c)
for r in p1:
r.set_edgecolor(c)
Putting it together
-------------------
Following is a simple example of how to use the class library
This is examples/agg_oo.py in the matplotlib src distribution, also
found (like all examples) at http://matplotlib.sf.net/examples
#!/usr/bin/env python
"""
A pure OO (look Ma, no pylab!) example using the agg backend
"""
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
ax.plot([1,2,3])
ax.set_title('hi mom')
ax.grid(True)
ax.set_xlabel('time')
ax.set_ylabel('volts')
canvas.print_figure('test')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment