python plot
about plot in python
- 1 matplotlib(2006-09-06)
- 1.1 output multiple figures in one script
- 1.2 disable the popup window in un-popup environ
- 1.3 2006-10-21 change color of hist()
- 1.4 2006-10-28 change color and alpha of scatter()
- 1.5 2006-10-03 bug in matplotlib when it comes to choose numpy, numeric or numarray
- 1.6 2007-06-15 install basemap toolkits
- 1.7 2007-12-17 encoding issue to output in svg format
- 1.8 2007-05-08 3D plot in python by matplotlib
- 1.9 2007-10-29 legends for scatter()
- 1.10 2008-09-19 legends for hist()
- 1.11 2008-05-15 click drawing objects to see more info
- 1.12 2008-09-28 control font size of various parts of a figure
- 1.13 2008-10-01 plots sharing x-axis or overlapping plots with two different scales
- 1.14 2008-12-28 transformation between figure coordinates and axe coordinates
- 2 rpy(2006-09-06)
- 3 networkx(2006-12-21)
- 4 2009-2-17 binary image data from PIL
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.
- set picker=True in the instantiation of an artist
- make sure self._picker=picker is in __init__() of that artist or its ancestors.
- 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).
- nx_pylab.py and axes.py were changed accordingly (repositary os_files contains their different versions).
- run 'import pylab, networkx' as root in python console to update .pyc files.
- 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
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_dataFor 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()