Pylab is a procedural interface to the matplotlib object-oriented plotting library. It can be installed via apt: sudo apt-get install python-matplotlib python-gtk2 To find out what you can do with it have a look at the [[http://matplotlib.sourceforge.net/pylab_commands.html|Pylab Command Overview]] or the [[http://matplotlib.sourceforge.net/|Matplotlib Site]] ====== Control axis ticks ====== by setting tick locations and tick labels It is also possible to rotate long labels: pylab.xticks( arange(12), calendar.month_name[1:13], rotation=17 ) ====== Plots with date axes ====== Use pylab.plot_date and the boolean parameters xdate and ydate date2num takes datetime instance or a sequence of datetimes as parameter and converts it/them to float(s). pylab.plot_date(dates,values, xdate=True, ydate=False) ====== Format Date Axes ====== To show hours on the X-Axis: import pylab from matplotlib.dates import DateFormatter,HourLocator pylab.plot_date(pylab.date2num(times), values, "b-", xdate=True, ydate=False, label="memory use" ) axes=pylab.gca() # Display the time of day every 2 hours axes.xaxis.set_major_locator(HourLocator(interval=2)) axes.xaxis.set_major_formatter(DateFormatter('%H:%M')) # Display a small tick every hour axes.xaxis.set_minor_locator(HourLocator()) To show days on the X-Axis. import pylab from matplotlib.dates import DateFormatter,DayLocator, HourLocator pylab.plot_date(times,values) # plot data # Display date at beginning of each day pylab.gca().xaxis.set_major_locator(DayLocator()) pylab.gca().xaxis.set_major_formatter(DateFormatter('%d.%b %Y')) # display a small tick every 6 hours pylab.gca().xaxis.set_minor_locator(HourLocator(byhour=(0,6,12,18))) ====== Set Axis Min/Max ====== pylab.plot(values) pylab.axis(ymax=100) # or ymin|xmax|xmin ( Note: its important to call pylab.axis() AFTER the plot command! ) pylab.show() ====== Change Font Size of Axis Labels ====== fontsize = 8 for tick in pylab.gca().xaxis.get_major_ticks(): tick.label1.set_fontsize(fontsize) ====== Plot lines ====== Draw a horizontal line at y=60 from xmin to xmax pylab.axhline(60,color="g", linestyle="--", label="free speed") ====== Plot Histograms ====== n,bins,patches = pylab.hist(values, noOfBins) ====== Kernel Density ====== import pylab import scipy import numpy # get data from somewhere data = numpy.random.normal(0,1,1000) # Important Note: Make sure your data is float. If your data is int it does not work for some reason! # histogram of data pylab.hist(data,50, normed=True) # add kernel density plot with gaussian kernel kernel = scipy.stats.kde.gaussian_kde(data) ind = numpy.linspace(-5,5,100) kdepdf = kernel.evaluate(ind) pylab.plot(ind, kdepdf,'r',linewidth=2) see * http://jpktd.blogspot.com/2009/03/using-gaussian-kernel-density.html * http://www.scipy.org/SciPyPackages/Stats ====== ECDF ====== import numpy import statsmodels.distributions ecdf = statsmodels.distributions.ECDF(data) x = numpy.linspace(min(data), max(data)) y = ecdf(x) pylab.plot(x,y) # or pylab.step(x, y) ====== Donut plot ====== Is (unsurprisingly) made from pie plots. A very good example is here http://matplotlib.1069221.n5.nabble.com/how-to-draw-concentric-donuts-chart-tp43408p43412.html I needed just a clean, simple "binary" donut, so I simplified that code. {{:data.png?300|}} # thanks to Joe Kington http://matplotlib.1069221.n5.nabble.com/how-to-draw-concentric-donuts-chart-tp43408p43412.html def make_pie(percent, text): import matplotlib.pyplot as plt import numpy as np c1 = '#9999FF' c2 = '#FF9999' fig, ax = plt.subplots() ax.axis('equal') width = 0.15 kwargs = dict(colors=[c1, c2], startangle=180, counterclock=False) outside, _ = ax.pie([percent, 1-percent], radius=1, pctdistance=1-width/2, **kwargs) plt.setp( outside, width=width, edgecolor='white') kwargs = dict(size=20, fontweight='bold', va='center', color=c1) ax.text(0, 0, "{0}% {1}".format(percent*100, text), ha='center', **kwargs) plt.show() make_pie(0.95, "of your data\n is made up") ====== Plot (stack) bars ====== Use pylab.bar to plot (stack) bars: bar(left, height, width=0.8, bottom=0, color=None, edgecolor=None, linewidth=None, yerr=None, xerr=None, ecolor=None, capsize=3, align='edge', orientation='vertical', log=False) #left - the x coordinates of the left sides of the bars #height - the heights of the bars #bottom - the y coordinates of the bottom edges of the bars #xerr, yerr - use to generate errorbars on the bar chart To plot stack bars use the argument "bottom", for example: width=0.8 heights1 = (20, 35, 30, 35, 27) #heights of bar1 heights2 = (25, 32, 34, 20, 25) #heights of bar2 bar1 = pylab.bar(arange(5), heights1, width, color='r') bar2 = pylab.bar(arange(5), heights2, width, color='y', bottom=heights1) ====== Rotate xticklabels to vertical ====== labels = pylab.getp(pylab.gca(),'xticklabels') # getproperty xticklabels from current axes pylab.setp(labels, rotation='vertical') ====== Add text ====== Add text in string s to axis at location x,y (default: data coords). It is also possible to specify text in axis coords (0,0 lower left and 1,1 upper right). text(x, y, s, fontsize=12) ====== Add text with Umlauts ====== text(x, y, unicode('hübsche Umlaute: ä ü ö', 'latin-1')) ====== Draw colored area / belt ("band") ====== To draw a belt do: pylab.fill_between(x,ylower, yupper, color='blue', alpha=0.1) ====== Mark/colour/paint areas ====== check [[http://matplotlib.sourceforge.net/examples/pylab_examples/axhspan_demo.html this example]] to see how it looks like. eg. to mark months in a plot: # get day of the year aug=int(datetime(2008,8,1).strftime("%j")) sept=int(datetime(2008,9,1).strftime("%j")) okt=int(datetime(2008,10,1).strftime("%j")) nov=int(datetime(2008,11,1).strftime("%j")) # plot areas subplot.axvspan(aug-0.5, sept-0.5, facecolor='0.5', alpha=0.2) subplot.axvspan(okt-0.5, nov-0.5, facecolor='0.5', alpha=0.2) # add descriptive text subplot.text( aug, 13500, 'August') subplot.text( sept, 13500, 'September') subplot.text( okt, 13500, 'October') '' also works horizontally using: subplot.axhspan(ymin,ymax) ====== Legends ====== ===== Add legend ===== In order to display a lagend you need to label your plots. For example pylab.plot_date(pylab.date2num(dates),speeds,"b-", xdate=True, ydate=False, label="taxi speeds") # the plot should be named "taxi speeds" in the legend pylab.legend() # add the legend to the plot pylab.show() '' ===== Legends outside of plot ===== Often there simply is no room to put the legend inside a plot. There are several approaches to put it partly or completely outside the plot. This [[http://stackoverflow.com/questions/4700614/how-to-put-the-legend-out-of-the-plot|stackoverflow]] thread shows how to use the bbox_to_anchor keyword to move the legend partly outside the plot: ax = plt.subplot(111) #ax.plot(something) ax.legend(bbox_to_anchor=(1.1, 1.05)) Alternatively the thread show how to shrink the current plot's width: this gains some space outside the plot where the legend can be put. ax = plt.subplot(111) #ax.plot(plot something) # Shink current axis by 20% box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.8, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) ===== Font properties of legends ===== Sometimes simply shrinking the legend font helps to improve the visibility of data in a plot: from matplotlib.font_manager import FontProperties fontP = FontProperties() fontP.set_size('xx-small') legend([plot1], "title", prop = fontP) ====== Save Figure ====== pylab.plot(...) pylab.savefig("my_figure.png", format="png") ====== Subplots ====== To create a subplot with 2 lines, and 1 Column, and switch to the first image: pylab.subplot(211) # plot first chart... # now switch to the second image pylab.subplot(212) # plot second chart ====== Using Pylab in CGI Scripts ====== Its necessary to do a few things before importing the pylab module: import os os.environ[ 'HOME' ] = '/tmp/'#set HOME environment variable to a directory the httpd server can write to import matplotlib matplotlib.use( 'Agg' )#use a non-gui backend. # Now pylab can be imported without errors import pylab import sys #Create your plot like you normally would, then return it to the browser by doing the following: print "Content-Type: image/png\n" pylab.savefig(sys.stdout, format='png' ) ====== Adding color to plots ====== from random import choice colors = ['#FFFFCC','#FFFF99','#FFFF66','#FFFF33','#FFFF00','#FFCCFF','#FFCCCC','#FFCC99','#FFCC66','#FFCC33','#FFCC00','#FF99FF','#FF99CC','#FF9999','#FF9966','#FF9933','#FF9900','#FF66FF','#FF66CC','#FF6699','#FF6666','#FF6633','#FF6600','#FF33FF','#FF33CC','#FF3399','#FF3366','#FF3333','#FF3300','#FF00FF','#FF00CC','#FF0099','#FF0066','#FF0033','#FF0000','#CCFFFF','#CCFFCC','#CCFF99','#CCFF66','#CCFF33','#CCFF00','#CCCCFF','#CCCCCC','#CCCC99','#CCCC66','#CCCC33','#CCCC00','#CC99FF','#CC99CC','#CC9999','#CC9966','#CC9933','#CC9900','#CC66FF','#CC66CC','#CC6699','#CC6666','#CC6633','#CC6600','#CC33FF','#CC33CC','#CC3399','#CC3366','#CC3333','#CC3300','#CC00FF','#CC00CC','#CC0099','#CC0066','#CC0033','#CC0000','#99FFFF','#99FFCC','#99FF99','#99FF66','#99FF33','#99FF00','#99CCFF','#99CCCC','#99CC99','#99CC66','#99CC33','#99CC00','#9999FF','#9999CC','#999999','#999966','#999933','#999900','#9966FF','#9966CC','#996699','#996666','#996633','#996600','#9933FF','#9933CC','#993399','#993366','#993333','#993300','#9900FF','#9900CC','#990099','#990066','#990033','#990000','#66FFFF','#66FFCC','#66FF99','#66FF66','#66FF33','#66FF00','#66CCFF','#66CCCC','#66CC99','#66CC66','#66CC33','#66CC00','#6699FF','#6699CC','#669999','#669966','#669933','#669900','#6666FF','#6666CC','#666699','#666666','#666633','#666600','#6633FF','#6633CC','#663399','#663366','#663333','#663300','#6600FF','#6600CC','#660099','#660066','#660033','#660000','#33FFFF','#33FFCC','#33FF99','#33FF66','#33FF33','#33FF00','#33CCFF','#33CCCC','#33CC99','#33CC66','#33CC33','#33CC00','#3399FF','#3399CC','#339999','#339966','#339933','#339900','#3366FF','#3366CC','#336699','#336666','#336633','#336600','#3333FF','#3333CC','#333399','#333366','#333333','#333300','#3300FF','#3300CC','#330099','#330066','#330033','#330000','#00FFFF','#00FFCC','#00FF99','#00FF66','#00FF33','#00FF00','#00CCFF','#00CCCC','#00CC99','#00CC66','#00CC33','#00CC00','#0099FF','#0099CC','#009999','#009966','#009933','#009900','#0066FF','#0066CC','#006699','#006666','#006633','#006600','#0033FF','#0033CC','#003399','#003366','#003333','#003300','#0000FF','#0000CC','#000099','#000066','#000033','#000000'] pylab.bar(h, prev, width,color=choice(colors)) ====== Selecting color from colormaps ====== Found [[https://geetduggal.wordpress.com/2011/08/22/grabbing-individual-colors-from-color-maps-in-matplotlib/|here]] Choose good colormap ([[http://matplotlib.org/examples/color/colormaps_reference.html|reference]]) and call it as function with a parameter between 0 and 1 import pylab as p c1 = p.cm.gnuplot2(0.3) c2 = p.cm.gnuplot2(0.7) p.plot(range(0, 5), color=c1) p.plot(range(4, 9), color=c2) p.show() ====== Make "customised" legends ====== Not very elegant but googling helped me doing the job: these lines are never plotted, only used for building a legend. from matplotlib.lines import Line2D line0 = Line2D(range(1), range(1), lw=4,color='darkgreen' ) line1 = Line2D(range(1), range(1), lw=4,color='skyblue' ) pylab.legend((line0,line1),('weekdays','weekends'),loc='best') ====== Show legend outside plot ====== import pylab pylab.figure() pylab.subplot(111) pylab.subplots_adjust(right=0.7) pylab.plot([1,6,11],label="1) label very long") pylab.plot([2,6,10],label="2) label") #Legende 1,1: ausrichtung rechts neben der Grafik; 0,1 unten neben der Grafik beginnen pylab.legend(loc=(1.1,0.1)) #show legend on the right side of the chart pylab.show() ====== Axis Labels ====== import pylab pylab.plot(....) pylab.axes().set_xlabel("hour") pylab.axes().set_ylabel("speed") ====== Format axes ====== import pylab pylab.figure() pylab.axes([0.1,0.1,0.71,0.8]) pylab.plot([0,1],[0,1],label="line 1") pylab.hold(1) pylab.plot([0,1],[1,0.5],label="line 2") pylab.legend(loc=(1.03,0.2)) pylab.show() ====== Overwrite Legend Function ====== Function for overwriting: def legend(*args, **kwargs): """ Overwrites the pylab legend function. It adds another location identfier 'outer right' which locates the legend on the right side of the plot The args and kwargs are forwarded to the pylab legend function """ if kwargs.has_key('loc'): loc = kwargs['loc'] loc = loc.split() if loc[0] == 'outer': # make a legend with out the location kwargs.pop('loc') # remove the location setting from the kwargs leg = pylab.legend(loc=(0,0), *args, **kwargs) frame = leg.get_frame() currentAxes = pylab.gca() currentAxesPos = currentAxes.get_position() # scale plot by the part which is taken by the legend plotScaling = frame.get_width()/currentAxesPos[2] if loc[1] == 'right': # scale the plot currentAxes.set_position((currentAxesPos[0],currentAxesPos[1],currentAxesPos[2]*(1-plotScaling),currentAxesPos[3])) # set x and y coordinates of legend. leg._loc = (1 + leg.axespad, 1 - frame.get_height()) pylab.draw_if_interactive() return leg return pylab.legend(*args, **kwargs) '' Test the function: pylab.plot([1,6,11],label="1) label") pylab.plot([2,6,10],label="2) label") pylab.plot([3,6,9],label ="3) label") pylab.plot([4,6,8],label ="4) label") pylab.title("Legend override (outer right)") pylab.grid() legend(loc='outer right') pylab.show() source: : http://www.mail-archive.com/matplotlib-users@lists.sourceforge.net/msg04256.html ====== Annotations ====== Use [[http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.annotate|annotations]] to enrich your plots with additional information. More Code Samples [[http://matplotlib.sourceforge.net/examples/pylab_examples/annotation_demo2.html|here]]] ====== Continuously updating a plot ====== The easy (but grossly inefficient) way: import pylab import time import random x=[] pylab.figure(1) pylab.subplot(111) for i in range (50): x.append(random.randint(0,100)) pylab.cla() pylab.plot(x) time.sleep(1) ====== Contour Plot ====== ===== Save Contour Plot as MIF ===== Here is a small function to save a contour plot as a MIF File (so it can be displayed in QGis etc.) import numpy.random import pylab def saveAsMIF(contour_plot, filename): coll = contour_plot.collections mid=file("%s.mid" %filename, "w") mif=file("%s.mif"%filename, "w") mif.write("""Version 300\nCharset "WindowsLatin1"\nDelimiter ","\nCOLUMNS 1\nLevel Integer\n""") mif.write("""DATA\n""") for level in range(0,len(coll)): for path in coll[level].get_paths(): polygon = path.to_polygons()[0] mif.write("PLINE %d\n" % len(polygon)) for c in polygon: mif.write("%f %f\n" % (c[0], c[1]) ) mid.write('"%d""\n' % level ) mid.close() mif.close() # example x=numpy.arange(100)/100.0 + 16.0 y=numpy.arange(100)/100.0 + 48.0 z= numpy.random.rand(100,100) C=pylab.contour(x,y,z) saveAsMIF(C,"test") ======= 3D plotting ======= 3D support was dropped by matplotlib but there are alternatives. One is [[http://code.enthought.com/projects/mayavi/docs/development/html/mayavi/mlab.html Mayavi2's mlab API]]. sudo apt-get install mayavi2 Then you can use it in your python scripts from enthought.mayavi import mlab ======= Resize Figure ======= fig.set_size_inches(20,15,forward=True) ====== Multiple Y-Axes ====== fig = pylab.figure() ax1 = fig.add_subplot(111) # plot something on the first pair ax1.plot(range(100)) ax1.axis(ymin=0, ymax=100) # set scale # get a second pair of axes and plot something else ax2 = ax1.twinx() ax2.plot(range(100)) ax2.axis(ymin=0, ymax=1000) ====== ggplot ====== Pretty plots ahead - [[https://github.com/yhat/ggplot|ggplot]] is a port of R's ggplot2, has tight integration with pandas and is easy to install. pip install ggplot You can also use it to switch plot styles in [[http://matplotlib.org/users/style_sheets.html|matplotlib]]: import matplotlib.pyplot as plt plt.style.use('ggplot') You need at least matplotlib 1.4.x, which might not be what your package provider offers. You can upgrade matplotlib with pip, but I ran into a quirk on Ubuntu 14.04 during installation. Here's a [[https://mlbernauer.wordpress.com/2014/12/06/upgrading-from-matplotlib-1-3-1-to-1-4-1-in-ubuntu-14-04/|quick fix]].