plotting variables vs. time

Anything that doesn't fit elsewhere.
Post Reply
srahim2

plotting variables vs. time

Post by srahim2 »

I needed help executing a state axis instead of a shape plot, one where I can specify what is being graphed instead of voltage. What's the syntax for the state axis?
ted
Site Admin
Posts: 6305
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Post by ted »

All you need is a Graph, with whatever additional statements are required to specify
--the variables that are to be plotted
--how NEURON will update the plots in the course of a simulation
--position, size, and scaling of the graph
--additional labels, if any
Read about the Graph class here
http://www.neuron.yale.edu/neuron/stati ... graph.html

As far as graph updating is concerned, you will find all kinds of strange looking code in
ModelDB and elsewhere. The best practice is to just let the standard run system take
care of it for you. You can read about this in The NEURON Book--look in the Index for
standard run system / plotting system
especially
standard run system / plotting system / graphLists
and
standard run system / plotting system / incorporating Graphs and objects

But it's even quicker to just steal code from a session file.

Suppose you have a model that has a default section called soma with hh, and you use
the NEURONMainMenu toolbar to create a Voltage axis graph of v(0.5) vs. t, a Current
axis graph of soma.ik(0.5) vs. t, and a State axis graph of soma.m_hh(0.5) vs. t. Also,
you use each Graph's "Change text" to write a label on the graph ("voltage axis",
"current axis", or "state axis" as appropriate). Then use the Print & File Window Manager
(PFWM) to select those three graphs and save them to a session file (read how in the
FAQ list). Finally, open that ses file with a text editor.

Here's what it will look like:

Code: Select all

objectvar save_window_, rvp_
objectvar scene_vector_[8]
objectvar ocbox_, ocbox_list_, scene_, scene_list_
{ocbox_list_ = new List()  scene_list_ = new List()}
{
save_window_ = new Graph(0)
save_window_.size(0,5,-80,40)
scene_vector_[5] = save_window_
{save_window_.view(0, -80, 5, 120, 1071, 66, 300.48, 200.32)}
graphList[0].append(save_window_)
save_window_.save_name("graphList[0].")
save_window_.addexpr("v(.5)", 1, 1, 0.8, 0.9, 2)
save_window_.label(0.629393, 0.392971, "voltage axis", 2, 1, 0, 0, 1)
}
{
save_window_ = new Graph(0)
save_window_.size(0,5,-1,1)
scene_vector_[6] = save_window_
{save_window_.view(0, -1, 5, 2, 1069, 333, 300.48, 200.32)}
graphList[1].append(save_window_)
save_window_.save_name("graphList[1].")
save_window_.addvar("soma.ik( 0.5 )", 1, 1, 0.8, 0.9, 2)
save_window_.label(0.261981, 0.819489, "current axis", 2, 1, 0, 0, 1)
}
{
save_window_ = new Graph(0)
save_window_.size(0,5,0,1)
scene_vector_[7] = save_window_
{save_window_.view(0, 0, 5, 1, 1064, 599, 300.48, 200.32)}
graphList[2].append(save_window_)
save_window_.save_name("graphList[2].")
save_window_.addvar("soma.m_hh( 0.5 )", 1, 1, 0.8, 0.9, 2)
save_window_.label(0.332268, 0.479233, "state axis", 2, 1, 0, 0, 1)
}
objectvar scene_vector_[1]
{doNotify()}
Let's analyze the code for the voltage axis graph to discover its underlying pattern, and
figure out how we might reuse it for our own purposes.

This

Code: Select all

{
save_window_ = new Graph(0)  // creates but does not display a new Graph
  // that lets us control its size and scaling before it is even drawn to the screen
save_window_.size(0,5,-80,40)  // axis scaling
scene_vector_[5] = save_window_
{save_window_.view(0, -80, 5, 120, 1071, 66, 300.48, 200.32)}  // draws it on the screen
  // at a user-specified location (5th and 6th args) and size (last 2 args)
graphList[0].append(save_window_)  // graphList[0] is for all graphs whose y values 
  // are to be plotted vs. t
save_window_.save_name("graphList[0].")
save_window_.addexpr("v(.5)", 1, 1, 0.8, 0.9, 2)  // adds v(0.5) to this graph's pliot list
  // also specifies line color and style, locaton on canvas where "v(.5)" will be printed
save_window_.label(0.629393, 0.392971, "voltage axis", 2, 1, 0, 0, 1)  // just prints the 
  // string "voltage axis" on the canvas at specified location, color etc.)
}
is the code that sets up the voltage axis graph, with explanatory comments by me.
Be sure to read the Graph class's documentation for a more detailed description
of the various graph methods that are being called. Also, I'm doing this from memory
and may have made a mistake.

Suppose you wanted to use hoc statements to create a graph that plots membrane
potential at the 0.1 location of apical[3] and the (0.4) location of basilar[21]. You want the
x axis to run from 0 to tstop, and the y axis to run from -10 to +5. Here's how you might
follow this pattern to do that:

Code: Select all

objref vg
vg = new Graph(0)  // creates but does not display a new Graph
vg.size(0,tstop,-10,5)  // axis scaling
// forget about the scene_vector stuff
vg.view(0, -10, tstop, 15, 200, 200, 300.48, 200.32)}  // draws it on the screen
  // at a user-specified location (5th and 6th args) and size (last 2 args)
graphList[0].append(vg)  // graphList[0] is for all objects that are to be 
  // updated at integer multiples of dt
// forget about the save_name stuff
vg.addexpr("apical[3].v(.1)", 1, 1, 0.8, 0.9, 2)
vg.addexpr("basliar[21].v(.4)", 1, 1, 0.8, 0.7, 2)  // put variable name a bit lower on the canvas
vg.label(0.4, 0.9, "two at once!", 2, 1, 0, 0, 1)
This will put the graph on your screen at (200, 200). If you don't like where it is, or want
to change the position of the labels and/or color/linestyle of the traces, just drag it to a
better location and use the graph's own menu to make whatever changes you like.
Then use the PFWM to save it to a session file and steal the new coordinates, line
style args, etc. from that file.

Now you're ready to analyze the original ses file and see the pattern that underlies the
code for the current axis and state axis graphs. graphList[1] is for graphs whose y
values are to be plotted vs. t - 0.5*dt, and graphList[2] is for graphs whose y values are
to be plotted vs. t + 0.5*dt. They are useful only if you are using the Crank-Nicholson
method (secondorder == 2) and want the plots of ionic currents and state variables to
be second order correct. If you are using the adaptive integrators (cvode), all variables
are computed at the same t and plots generated with graphList[1] and graphList[2] are
identical to plots of the same variables that are generated with graphList[0].

An exercise for the reader: write an obfunc that spawns a new graph that plots a
user-specified variable vs. t. It should accept these arguments:
--xy location on screen
--a strdef that is the name of the variable to be plotted
--y axis scaling (i.e. ymin and ymax)
Post Reply