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 Pylab Command Overview or the Matplotlib Site
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 )
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)
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)))
pylab.plot(values) pylab.axis(ymax=100) # or ymin|xmax|xmin ( Note: its important to call pylab.axis() AFTER the plot command! ) pylab.show()
fontsize = 8 for tick in pylab.gca().xaxis.get_major_ticks(): tick.label1.set_fontsize(fontsize)
Draw a horizontal line at y=60 from xmin to xmax
pylab.axhline(60,color="g", linestyle="--", label="free speed")
n,bins,patches = pylab.hist(values, noOfBins)
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
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)
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.
# 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")
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)
labels = pylab.getp(pylab.gca(),'xticklabels') # getproperty xticklabels from current axes pylab.setp(labels, rotation='vertical')
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)
text(x, y, unicode('hübsche Umlaute: ä ü ö', 'latin-1'))
To draw a belt do:
pylab.fill_between(x,ylower, yupper, color='blue', alpha=0.1)
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)
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() ''
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 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))
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)
pylab.plot(...) pylab.savefig("my_figure.png", format="png")
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
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' )
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))
Found here
Choose good colormap (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()
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')
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()
import pylab pylab.plot(....) pylab.axes().set_xlabel("hour") pylab.axes().set_ylabel("speed")
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()
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
Use annotations to enrich your plots with additional information. More Code Samples here]
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)
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 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
fig.set_size_inches(20,15,forward=True)
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)
Pretty plots ahead - 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 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 quick fix.