The bad news is no, but the good news is that it's easy to make your own procedureI use the following command to plot voltage in soma and a dendritic compartment but it the y-axis is set at -1 to 1.

newPlotI()

{

graphItem.addvar("L1CR[0].soma.v(0.5)",2,1)

graphItem.addvar("L1CR[0].dend[65].v(0.5)",3,1)

}

However, if I use the plot command below for the soma only, then the y-axis is scaled automatically.

plotVoltage("Cell.soma.v( 0.5 ),2)

Is there a way to set the y-axis scaling with the first newPlotI procedure?

that will let you specify whatever y axis scaling you like.

An aside: I'm not aware of any procedure called plotVoltage(). Is that something you

found somewhere in ModelDB or on the WWW? It doesn't seem to be built into NEURON.

Back to the main thread of this discussion--

newPlotI() is the very procedure that is executed when you use the NEURON Main Menu

toolbar to spawn a new "Current axis" graph. This procedure, and its close cousins

newPlotV() and newPlotS(), are defined in stdrun.hoc, which you will find in

nrn/share/nrn/lib/hoc under UNIX / Linux / OS X, or c:\nrnxx\lib\hoc under MSWin (where

the xx is the version number). In fact, here is the code in stdrun.hoc that generates the

"dropdown menu" that appears when you click on the toolbar's Graph button:

Code: Select all

```
proc graphmenu() {
xmenu("Graph", 1)
xbutton("Voltage axis", "newPlotV()")
xbutton("Current axis", "newPlotI()")
xbutton("State axis", "newPlotS()")
xbutton("Shape plot", "newshapeplot()")
xbutton("Vector movie", "newvectorplot()")
xbutton("Phase Plane", "newphaseplane()")
xbutton("Grapher", "load_file(\"grapher.hoc\") makegrapher(1)")
xmenu()
}
```

Scrolling a bit farther into stdrun.hoc, we discover the definitions of newPlotV(),

newPlotI(), and newPlotS():

Code: Select all

```
proc newPlotV() {
newPlot(0,tstop,-80,40)
graphItem.save_name("graphList[0].")
graphList[0].append(graphItem)
graphItem.addexpr("v(.5)")
}
proc newPlotI() {
newPlot(0,tstop,-1,1)
graphItem.save_name("graphList[1].")
graphList[1].append(graphItem)
}
proc newPlotS() {
newPlot(0,tstop,0,1)
graphItem.save_name("graphList[2].")
graphList[2].append(graphItem)
}
```

have an x axis that runs from 0 to tstop, but the y axis range will be

-80 to 40 mV for a "Voltage axis" plot,

-1 to 1 for a "Current axis" plot, and

0 to 1 for a "State axis" plot.

And of course this guess is correct.

So suppose you want a Voltage axis graph, but you want the y axis to span a range

other than -80 to +40? Easy. Write your own procedure that accepts the min and max

y values as arguments. A first stab at this would be

Code: Select all

```
proc myPlotV() {
newPlot(0,tstop,$1,$2)
graphItem.save_name("graphList[0].")
graphList[0].append(graphItem)
// graphItem.addexpr("v(.5)")
}
```

myPlotV(-10, 10)

should bring up a graph whose y axis runs from -10 to +10. Try it. Notice that I commented

out graphItem.addexpr("v(.5)"), so this new graph won't come up with membrane

potential at the middle of the default section as its first variable to plot. You'll have to use

graphItem.addvar() to specify what you want plotted (that's probably what you want to

do anyway).

Also notice that I haven't bulletproofed this code at all--what will happen if the first

argument is larger than the second? Nonsense results can be prevented by inserting a

conditional statement just before the newPlot() call, e.g.

Code: Select all

```
proc myPlotV() {
if ($1>=$2) {
print "myPlotV error--first argument must be smaller than second argument"
stop
}
newPlot(0,tstop,$1,$2)
graphItem.save_name("graphList[0].")
graphList[0].append(graphItem)
// graphItem.addexpr("v(.5)")
}
```

**Why are there different graphLists?**

Graphs spawned by newPlotV(), newPlotI(), and newPlotS() are appended to one of

three graphLists, so that they will be automatically updated during simulation execution.

As noted at the end of chapter 7 in The NEURON Book, when fixed time step integration

is used, graphList[0], [1], and [2] differ in the x coordinates used for plotted points. For

graphList[0] each variable is plotted vs. the current value of t, but for graphList[1] the x

coordinates are t - 0.5*dt, and for graphList[2] the x coords are t + 0.5*dt.

The reason for this is that, if you use NEURON's Crank-Nicholson integrator (by

assigning

**secondorder = 2**-- see the Programmer's Reference documentation of

secondorder), voltages will be second order correct at integral multiples of dt, but

currents and states will be second order correct half a time step earlier or later,

respectively. By plotting voltages in Voltage axis graphs, currents in Current axis graphs,

and states in State axis graphs, the plotted points preserve second order accuracy in

time.

"But doesn't this mess up the accuracy of current and state graphs when the default

backward Euler method is used?" No, because backward Euler is only first order

accurate in time, i.e. local error of the solution is proportional to dt, the size of the time

step. This means that there isn't a specific time in the interval from (t - 0.5*dt) to (t + 0.5*dt)

at which voltages, currents, and states are first order correct--they're equally

(in)accurate over that entire interval.

When adaptive integration ("CVODE") is used, all variables are computed to the same

degree of accuracy at identical times, and all "Voltage axis," "Current axis," and "State

axis" graphs plot their variables at identical values of t.