Personal tools
You are here: Home log python python plot
Document Actions

python plot

about plot in python

1   matplotlib(2006-09-06)

1.1   output multiple figures in one script

figure(1) is used to activate a number-specified figure and then savefig(filename). Check the pdf user's guide.

1.2   disable the popup window in un-popup environ

import matplotlib; matplotlib.use("Agg"), Agg could be other non-popup backend. Do this before `import pylab`. But if in one session, show() is called before this operation, it's gonna fail. You have to restart. Note: interactive != popup. 'interactive' means drawing after every plot command.

2008-08-28 This interactive mode has to be disabled in parallel (MPI) programs. potential error looks like this:

  File "/home/crocea/script/variation/src/__init__.py", line 21, in <module>
    import networkx as nx
  File "/var/lib/python-support/python2.5/networkx/__init__.py", line 127, in <module>
    from drawing import *
  File "/var/lib/python-support/python2.5/networkx/drawing/__init__.py", line 30, in <module>
    from nx_pylab import *
  File "/var/lib/python-support/python2.5/networkx/drawing/nx_pylab.py", line 44, in <module>
    import matplotlib.pylab
  File "/usr/lib/python2.5/site-packages/matplotlib-0.91.2-py2.5-linux-x86_64.egg/matplotlib/pylab.py", line 292, in <module>
    from matplotlib.pyplot import *
  File "/usr/lib/python2.5/site-packages/matplotlib-0.91.2-py2.5-linux-x86_64.egg/matplotlib/pyplot.py", line 37, in <module>
    new_figure_manager, draw_if_interactive, show = pylab_setup()
  File "/usr/lib/python2.5/site-packages/matplotlib-0.91.2-py2.5-linux-x86_64.egg/matplotlib/backends/__init__.py", line 24, in pylab_setup
    globals(),locals(),[backend_name])
  File "/usr/lib/python2.5/site-packages/matplotlib-0.91.2-py2.5-linux-x86_64.egg/matplotlib/backends/backend_gtkagg.py", line 10, in <module>
    from matplotlib.backends.backend_gtk import gtk, FigureManagerGTK, FigureCanvasGTK,\
  File "/usr/lib/python2.5/site-packages/matplotlib-0.91.2-py2.5-linux-x86_64.egg/matplotlib/backends/backend_gtk.py", line 40, in <module>
    cursors.MOVE          : gdk.Cursor(gdk.FLEUR),
RuntimeError: could not create GdkCursor object
1.2.1   2008-10-29 save figure in a web framework

Apart from import matplotlib; matplotlib.use("Agg"), some web framework enforces unicode in filename. While the Agg c++ backend might fail to understand the unicode filename. http://trac-hacks.org/ticket/2504:

File "build\bdist.win32\egg\tracmetrixplugin\mdashboard.py", line 324, in create_cumulative_chart
  fig.savefig(path)
File "G:\Python25\Lib\site-packages\matplotlib\figure.py", line 782, in savefig
  self.canvas.print_figure(*args, **kwargs)
File "G:\Python25\Lib\site-packages\matplotlib\backend_bases.py", line 1195, in print_figure
  **kwargs)
File "G:\Python25\Lib\site-packages\matplotlib\backends\backend_agg.py", line 397, in print_png
  self.get_renderer()._renderer.write_png(filename, self.figure.dpi.get())
TypeError: cannot return std::string from Unicode object

a simple trick will solve this:

filename = str(filename)  #convert unicode into normal python string
fig.savefig(filename)

1.3   2006-10-21 change color of hist()

trick is in **kwargs. It's never explained but goes deep into pylab's function. Function figure() of pylab.py shows you what those important parameters are. facecolor and edgecolor. i.e. n, bins, patches = hist(x, 100, normed=1, alpha=0.5, facecolor='r')

1.4   2006-10-28 change color and alpha of scatter()

Parameters: facecolor, edgecolor and color all work with scatter() but with these parameters, alpha won't work because scatter() has its own color specifying paramter, c. pylab.scatter(x,z, 10,c='r', alpha=.2)

1.5   2006-10-03 bug in matplotlib when it comes to choose numpy, numeric or numarray

With numpy installed, It says something like:

RuntimeError: module compiled against version 1000002 of C-API but this version of numpy is 1000000

If i remove numpy with numeric and numarray installed, it says:

Traceback (most recent call last):
 File "<stdin>", line 1, in ?
 File "/usr/lib/python2.4/site-packages/pylab.py", line 1, in ?
   from matplotlib.pylab import *
 File "/usr/lib/python2.4/site-packages/matplotlib/pylab.py", line 196, in ?
   import cm
 File "/usr/lib/python2.4/site-packages/matplotlib/cm.py", line 5, in ?
   import colors
 File "/usr/lib/python2.4/site-packages/matplotlib/colors.py", line 33, in ?
   from numerix import array, arange, take, put, Float, Int, where, \
 File "/usr/lib/python2.4/site-packages/matplotlib/numerix/__init__.py", line 73, in ?
   import numpy
ImportError: No module named numpy

Until i changed /usr/lib/python2.4/site-packages/matplotlib/numerix/__init__.py and inserted 'which = "numeric", "numarray"' after line 50. It worked.

1.6   2007-06-15 install basemap toolkits

download from basemap tarball from http://sourceforge.net/projects/matplotlib

unzip and cd into its directory

python setup.py build

sudo python setup.py install --prefix=/usr/local/

merge basemap into matplotlib's system directory:

sudo mv /usr/local/lib/python2.5/site-packages/matplotlib/toolkits/basemap/ /usr/lib/python2.5/site-packages/matplotlib/toolkits/

2008-09-23 another package python-mapnik emerged, looks better and easier.

1.7   2007-12-17 encoding issue to output in svg format

some strain names in stock are swedish. Encoding 'latin10' works but 'utf-8' doesn't. When outputting the stuff in svg format, it could go wrong:

File "lib-tk/Tkinter.py", line 1406, in __call__
  return self.func(*args)
File "/usr/lib/python2.5/site-packages/matplotlib/backends/backend_tkagg.py", line 650, in save_figure
  self.canvas.print_figure(fname)
File "/usr/lib/python2.5/site-packages/matplotlib/backends/backend_tkagg.py", line 188, in print_figure
  **kwargs)
File "/usr/lib/python2.5/site-packages/matplotlib/backends/backend_agg.py", line 497, in print_figure
  printfunc(filename, dpi, facecolor, edgecolor, orientation, **kwargs)
File "/usr/lib/python2.5/site-packages/matplotlib/backends/backend_svg.py", line 332, in print_figure
  self.figure.draw(renderer)
File "/usr/lib/python2.5/site-packages/matplotlib/figure.py", line 601, in draw
  for a in self.axes: a.draw(renderer)
File "/usr/lib/python2.5/site-packages/matplotlib/axes.py", line 1286, in draw
  a.draw(renderer)
File "/usr/lib/python2.5/site-packages/matplotlib/text.py", line 432, in draw
  ismath=self.is_math_text())
File "/usr/lib/python2.5/site-packages/matplotlib/backends/backend_svg.py", line 253, in draw_text
  self._svgwriter.write (svg)
File "codecs.py", line 638, in write
  return self.writer.write(data)
File "codecs.py", line 303, in write
  data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf6 in position 139: ordinal not in range(128)

The problem is the svg backend assumes the strict 'utf-8' encoding. It's too much to modify the svg backend. but decode the strain names and ignore the weird characters before feed them to the backend. like:

strain_name = strain_name.decode('utf-8', 'ignore')

1.8   2007-05-08 3D plot in python by matplotlib

not described on its website or official documentation.

http://www.scipy.org/Cookbook/Matplotlib/mplot3D has complete examples

/usr/lib/python2.5/site-packages/matplotlib/axes3d.py was modified to get all test_xxx() to work

a live example is in doc/math508/math508.py, class Math508_Final_Exam_3, function plot3D_pi_array()

1.8.1   2008-05-16 pick event not available in 3D plot

In axes3d.py , can see objects are inherited from art3d.py. In contrast to Artist in artist.py, pick() pickable(), set_picker, get_picker are not implemented.

1.9   2007-10-29 legends for scatter()

the scatter instance list cannot be omitted. for lines (plot()), it could be omitted.:

pscatter = pylab.scatter(xy_ls[0], xy_ls[1], c='r', alpha=0.6, faceted=False)
pscatter_ls.append(pscatter)
color_ls.append(color_number2genotype[color_number])
pylab.legend(pscatter_ls, color_ls, shadow = True)

1.10   2008-09-19 legends for hist()

By default, the legend function assigns a legend entry to every patch in the figure. A histogram has a number of patches depending the number of bins that user sets.

The histogram function, pylab.hist, returns a 3-element tuple, (n, bins, patches). Use the first patch to designate the plot.:

pylab.clf()
n1 = pylab.hist(score_ls1, 100, alpha=0.4, normed=1)
n2 = pylab.hist(score_ls2, 100, alpha=0.4, normed=1, facecolor='r')
pylab.legend([n1[2][0], n2[2][0]], ['candidate gene list', 'non-candidate gene list'])
pylab.show()

1.11   2008-05-15 click drawing objects to see more info

matploblib implemented pick event to let user to pick the objects by clicking. Check examples/pick_event_demo.py and examples/picker_demo.py from matplotlib source code. variation/src/GenomeBrowser.py's on_canvas_clik() was inspired by it.

1.11.1   2008-09-30 how picker event works and how to enable it

In matplotlib, all events are first picked by the underlying canvas window (such as NavigationToolbar2GTKAgg from matplotlib.backends.backend_gtkagg) then passed to the artist itself to handle. Artist.pick() (in artist.py, which is the ancestor of all artists) calls pickable(), which checks if self._picker is True, to see whether this artist is pickable. then it calls picker() or contains() to see whether the event is within itself or not, if yes, user-defined callback will be invoked.

So to enable picker_event.

  1. set picker=True in the instantiation of an artist
  2. make sure self._picker=picker is in __init__() of that artist or its ancestors.
  3. make sure the artist or its ancestor has contains() or get_picker().

No self._picker=picker is a common oversight. Like PolyCollection's ancestor PatchCollection (collection.py) defines a method 'contains()' while neither PolyCollection nor its ancestors have self._picker=picker in __init__(). In pymodule/ExonIntronCollection.py, a simple self._picker=picker completes the whole loop.

1.12   2008-09-28 control font size of various parts of a figure

Individual function like text, title, legend probably can accept arguments setting font size, label size, title size. Another way of doing this globally in a program is through rcParams:

from matplotlib import rcParams
rcParams['font.size'] = 6
rcParams['legend.fontsize'] = 6
#rcParams['text.fontsize'] = 6        #deprecated. use font.size instead
rcParams['axes.labelsize'] = 6
rcParams['axes.titlesize'] = 8
rcParams['xtick.labelsize'] = 6
rcParams['ytick.labelsize'] = 6

A data structure, defaultParams in file /usr/lib/python2.5/site-packages/matplotlib/rcsetup.py contains the names of all parameters that could be set.

1.13   2008-10-01 plots sharing x-axis or overlapping plots with two different scales

For plots sharing x-axis, check out shared_axis_demo.py, use sharex_foreign(), and shared_axis_across_figures.py, use sharey_foreign(), in matplotlib/examples. Basically two ways to get there.:

from pylab import figure, show
fig1 = figure()
fig2 = figure()
ax1 = fig1.add_subplot(111)
ax2 = fig2.add_subplot(111)
ax1.plot(numpy.random.rand(100), 'o')
ax2.plot(numpy.random.rand(100), 'o')
ax1.sharex_foreign(ax2)
ax2.sharex_foreign(ax1)
ax1.sharey_foreign(ax2)
ax2.sharey_foreign(ax1)

#OR 2nd way
t = arange(0.01, 5.0, 0.01)
s1 = sin(2*pi*t)
s2 = exp(-t)
s3 = sin(4*pi*t)
ax1 = subplot(311)
plot(t,s1)
setp( ax1.get_xticklabels(), fontsize=6)
## share x only
ax2 = subplot(312, sharex=ax1)
plot(t, s2)
# make these tick labels invisible
setp( ax2.get_xticklabels(), visible=False)
# share x and y
ax3 = subplot(313,  sharex=ax1, sharey=ax1)
plot(t, s3)

For overlapping plots with two scales, function twinx() is handy. Check out two_scales.py in matplotlib/examples.

ax1 = subplot(111)
t = arange(0.01, 10.0, 0.01)
s1 = exp(t)
plot(t, s1, 'b-')
xlabel('time (s)')
ylabel('exp')
# turn off the 2nd axes rectangle with frameon kwarg
ax2 = twinx()
s2 = sin(2*pi*t)
plot(t, s2, 'r.')
ylabel('sin')
ax2.yaxis.tick_right()

1.14   2008-12-28 transformation between figure coordinates and axe coordinates

version 0.91 from: http://www.scipy.org/Cookbook/Matplotlib/Transformations.

To manually apply a transformation t to coordinates x,y, you can use t.xy_tup(x,y). To reverse this transformation, use t.inverse_xy_tup(x,y).

Sometimes, you have to freeze axes if you are connecting points between them:

ax.transData.freeze()  # eval the lazy objects
ax.transAxes.freeze()
....
ax.transData.thaw()  # eval the lazy objects
ax.transAxes.thaw()

WARNING: 0.91 and 0.99 use totally different API in terms of this.

2   rpy(2006-09-06)

output plots in multiple pages
par(ask=TRUE) and use the postscript device. source: trellis user pdf manual.

3   networkx(2006-12-21)

There're several parameters related to color in drawing, like 'node_color', 'edge_color', 'font_color', etc. As networkx utilizes matplotlib(pylab) to do actual drawing, pylab's user guide is the right place to look for the values for these parameters, ('k'=black, 'c'=cyan, 'm'=magenta, 'w'=white etc).

3.1   2007-01-31 draw node boxes around labels in networkx

The purpose is to draw a same-height rectangle around node labels.

the node_shape offered by drawing/nx_pylab.py (which could be traced to pylab's scatter() in axes.py) expands in every direction given a scale list. However, scatter() offers parameter 'verts' which is omitted when it's called in nx_pylab.py. 'scale' of scatter works on 'verts' by expanding both x and y axis, which is again not ideal (because different-height ensues).

  1. nx_pylab.py and axes.py were changed accordingly (repositary os_files contains their different versions).
  2. run 'import pylab, networkx' as root in python console to update .pyc files.
  3. annot/DrawPredGOExptTFCompTF_Patterns.py showcased this new way of calling.

example:

nx.draw_networkx_nodes(g, pos, node_color='w', node_size=node_size_list, node_shape=None, alpha=1, \
  verts=[[-char_width/2, -char_height/2], [-char_width/2, char_height/2], [char_width/2, char_height/2], \
  [char_width/2, -char_height/2]])

4   2009-2-17 binary image data from PIL

  1. For encoders supported by tostring() including eps, gif, raw, xbm, zip, jpeg:

    img = PIL.Image.open(filename)
    img_data = img.tostring('jpeg', 'RBG')
    db_entry.field = img_data
    
  2. For unsupported encoders such as png, use StringIO:

    from qt import QImage
    from cStringIO import StringIO
    s = StringIO()
    im.save(s, "PNG")
    s.seek(0)
    image = QImage()
    image.loadFromData(s.read())   #or s.getvalue()
    
« November 2009 »
Su Mo Tu We Th Fr Sa
1234567
89101112 1314
1516171819 20 21
22232425262728
2930
 

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: