Raster plots and MATLAB
A colleague once told me: “in MATLAB, drawing a raster plot is a trivial, one line command”. True, but then you spend another 10 lines of code trying to make it not look like complete crap. Which is both time consuming and futile. In the end, you know you’re going to be spending half a day with Adobe Illustrator to fix it. But it does all start with one line of code.
Here’s some code to draw simple, one line raster plots:
function raster(in) if size(in,1) > size(in,2) in=in'; end axis([0 max(in)+1 -1 2]) plot([in;in],[ones(size(in));zeros(size(in))],'k-') set(gca,'TickDir','out') % draw the tick marks on the outside set(gca,'YTick', []) % don't draw y-axis ticks set(gca,'PlotBoxAspectRatio',[1 0.05 1]) % short and wide set(gca,'Color',get(gcf,'Color')) % match figure background set(gca,'YColor',get(gcf,'Color')) % hide the y axis box off
As an aside…
Looking for a wry take on MATLAB’s shortcomings from an anonymous neuroscientist? Try Abandon MATLAB. This blog’s posts include these gems:
Matlab doesn’t know how to draw one ball out of an urn containing one ball
The Mathworks don’t even know how to look up functions in their own global namespace
And this image (source):
Here’s an ugly hack to achieve a similar result with matplotlib. I doubt that the indentation will be preserved though.
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid.axislines import Subplot
def raster(spikes):
fig = plt.figure(figsize=(10,1))
ax = Subplot(fig, 111, frameon=False)
ax.plot([spikes,spikes], [np.ones((len(spikes))), np.zeros((len(spikes)))], ‘-k’)
ax.set_xlim([np.min(spikes), np.max(spikes)])
for loc in [“right”, “top”, “left”]:
ax.axis[loc].set_visible(False)
ax.axis[“bottom”].major_ticks.set_tick_out(True)
ax.axis[“bottom”].major_ticks.set_ticksize(10)
fig.add_axes(ax)
That all looks mighty complicated. I still think plotting is where Igor Pro wins. Thus:
Display Spikes
ModifyGraph mode=3,marker=10,msize=10
If you don’t want the axis on the left:
Display Spikes
ModifyGraph mode=3,marker=10,msize=10 , noLabel(left)=2,axThick(left)=0
This is so right. For years I wonder why can’t they just add the OR marker |
that will indeed turn it into one-liner.
That’s a very good point, Mickey. The ‘|’ marker is of course available in matplotlib, which reduces the plot line to:
ax.plot([spikes], [np.zeros((len(spikes)))], ‘|k’, ms=20)
There is a relatively simple way to create a multi-line raster as well: essentially, put your spikes into a fine-grain histogram (1-2ms bins) and put that array into imagesc().
Code (style adjustments as described above are still needed):
imagesc(histEdges+(0.5*binSize),[],spikeHist*-1) %This is the whole she-bang
colormap(gray) %This makes your -1 spikeHist tick marks black and your 0 values white/
Explanation of variables:
spikeHist=histc(spikeTimes,histEdges), where histEdges is the binning vector used to create the histogram, for example, something like the vector: -1000:binSize:1000 (binSize=1 or 2 ms), and spikeTimes is a (trial rows x n columns) array of spike times. (NaN-padded is best, but this is a different discussion).
The trick is aligning the x labels of the imagesc() output appropriately. The way to do it is to add half of your binning size to the xlabel vector (in my experience, this will align your ticks optimally with spike times). Precision may vary! But a raster is inherently limited in it’s temporal resolution (either you look at precise ticks over a shorter time span or imprecise ticks over a longer time span).
Maybe this also seems too complicated (and I agree, it’s cumbersome), but hopefully it gives people more ideas about what’s possible!