Hello,
I have downloaded a NEURON code and want to add a few lines to visualize the voltage propagation from a synaptic input site to the rest part of the neruon as time evolves. So far I only found some functions such as "Shape/PlotShape", but I am not sure whether they work or not. Can anyone tell me how to do it? Thanks!
voltage propagation in the whole cell
-
- Site Admin
- Posts: 6366
- Joined: Wed May 18, 2005 4:50 pm
- Location: Yale University School of Medicine
- Contact:
Re: voltage propagation in the whole cell
What kind of a visualization do you want? You could just plot the time course of v in different parts of the model vs. time in the same graph. Then you can compare the detailed time course of v at each of those locations.xiaosage wrote:want to . . . visualize the voltage propagation from a synaptic input site to the rest part of the neruon as time evolves.
Re: voltage propagation in the whole cell
Hi Ted,
Thanks for your reply! I actually want to see the voltage distribution in the whole cell, for example, as the movie shown below
http://cns.iaf.cnrs-gif.fr/files/dendritRE_short.mpg
Thanks!
Thanks for your reply! I actually want to see the voltage distribution in the whole cell, for example, as the movie shown below
http://cns.iaf.cnrs-gif.fr/files/dendritRE_short.mpg
Thanks!
-
- Site Admin
- Posts: 6366
- Joined: Wed May 18, 2005 4:50 pm
- Location: Yale University School of Medicine
- Contact:
Re: voltage propagation in the whole cell
Here's how to to generate such a graph by writing hoc code; it's even easier to do this with the GUI's tools.
First you'll need an instance of the PlotShape class, configured as a "shape plot," that will update at every fadvance.
Then you'll need to use the standard run system's movierun() instead of run().
Finally, when you're ready to run a simulation, use
If you want to make it run more slowly, specify the frame interval by using a hoc assignment statement that gives the parameter movie_frame_dur_ a value larger than 0.01 (seconds).
First you'll need an instance of the PlotShape class, configured as a "shape plot," that will update at every fadvance.
Code: Select all
// this assumes you have already loaded the standard run system
// e.g. by double clicking on nrngui.hoc or some other hoc file
// or by starting NEURON by executing nrngui
// or by including either load_file("nrngui.hoc") or load_file("stdrun.hoc")
// at the top of your program
objref ps
ps = new PlotShape()
fast_flush_list.append(ps)
ps.exec_menu("Shape Plot")
Code: Select all
load_file("movierun.hoc")
Code: Select all
movierun()
-
- Posts: 1
- Joined: Thu Nov 28, 2024 8:33 am
Re: voltage propagation in the whole cell
Hi,
I would like to do something similar for my project, and then export the plot, so that after the simulation I could have it saved as a "video" or something of sorts.
I have tried several approaches, but none seem to work.
Can you give me a hand on how to go about exporting the plot of the voltages changing over time?
I have made several different scripts (some with help from GPT and making use of other topics in the forum) to try to go about this, which I will go through below.
This first one is based on the implementation you suggested here, and it works regarding visualization of the voltages changing over time, but then I can't get it to save anything. Is there a way for me to do it?
This one makes use of the way to add a colorbar described in viewtopic.php?p=20058#p20058, and also the beforestep_py mod file described in viewtopic.php?t=3389. In this I was trying to avoid using a PlotShape directly, cause it wasn't working for me, but have had no success in getting it to actually plot or save something.
This last one makes use of the voltages for each time step that I saved in a csv file. It doesn't work in regards to saving the plot, but even if it did, I can't help but think it's an inefficient way to go about it. I know I have made some mistakes, so I was hoping to get some guidance on how to fix them and how to go about doing this... Apologies if my post is too confusing and if there is missing information.
I would like to do something similar for my project, and then export the plot, so that after the simulation I could have it saved as a "video" or something of sorts.
I have tried several approaches, but none seem to work.
Can you give me a hand on how to go about exporting the plot of the voltages changing over time?
I have made several different scripts (some with help from GPT and making use of other topics in the forum) to try to go about this, which I will go through below.
Code: Select all
def plot_view(folder=os.getcwd(),tmin=1e5,tmax=1e5,cell=None):
ps=h.PlotShape(True)
ps.variable("v")
#ps.scale(-80, 30)
h.fast_flush_list.append(ps)
ps.exec_menu("Shape Plot")
ps.exec_menu("Show Diam")
ps.exec_menu("View = plot")
output_dir="frames"
out=os.path.join(folder,output_dir)
os.makedirs(out, exist_ok=True) # Create directory if it doesn't exist
def save_files():
t=h.t
if t>=tmin and t>=tmax:
filename=f"frame_{t:.2f}.eps"
file=os.path.join(out,filename)
ps.printfile(file)
callback=h.beforestep_callback(cell.soma(0.5))
callback.set_callback(save_files)
return ps, callback
Code: Select all
def morphology_voltage_movie(cell, folder,cmap=cm.cool,tmin=1e5,tmax=1e5):
fig = go.FigureWidget()
fig.update_layout(
title="Membrane Voltage Over Time",
scene=dict(
xaxis=dict(title="X"),
yaxis=dict(title="Y"),
zaxis=dict(title="Z"),
)
)
# Extract the morphology
x_coords, y_coords, z_coords, arcs, diams, initial_v = [], [], [], [], [], []
for sec in cell.all:
for i in range(sec.n3d()):
x=sec.x3d(i)
y=sec.y3d(i)
z=sec.z3d(i)
arc=sec.arc3d(i)
diam=sec.diam3d(i)
x_coords.append(x)
y_coords.append(y)
z_coords.append(z)
arcs.append(arc)
diams.append(diam)
for sec in cell.all:
for seg in sec:
initial_v.append(seg.v)
# Normalize for the colormap
vmin, vmax = -100, 50 # Adjust based on expected voltage range
norm = cm.colors.Normalize(vmin=vmin, vmax=vmax)
colors = [f"rgb{tuple((np.array(cmap(norm(v)))[:3] * 255).astype(int))}" for v in initial_v]
scatter=go.Scatter3d(
x=x_coords,
y=y_coords,
z=z_coords,
mode='markers',
marker=dict(
size=5,
color=colors,
showscale=True,
colorbar=dict(title="Voltage (mV)"),
colorscale="Viridis"
),
text=[f"Voltage: {v:.2f} mV" for v in initial_v]
)
fig.add_trace(scatter)
# for sec in cell.all:
# for seg in sec:
# # x_coords.append(h.x3d(sec.arc3d(seg.x)))
# # y_coords.append(h.y3d(sec.arc3d(seg.x)))
# # z_coords.append(h.z3d(sec.arc3d(seg.x)))
# x_coords.append(seg.x_xtra)
# y_coords.append(seg.y_xtra)
# z_coords.append(seg.z_xtra)
# v_values.append(seg.v) # Initial voltage
output_dir="frames"
out=os.path.join(folder,output_dir)
os.makedirs(out, exist_ok=True) # Create directory if it doesn't exist
def update_plot():
"""
Callback to update the morphology plot with current voltage values.
"""
# Update voltage values
current_voltages = []
for sec in cell.all:
for seg in sec:
current_voltages.append(seg.v)
# Map voltage to colors
colors = [f"rgb{tuple((np.array(cmap(norm(v)))[:3] * 255).astype(int))}" for v in current_voltages]
scatter.marker.color = colors
scatter.text = [f"Voltage: {v:.2f} mV" for v in current_voltages]
# Save frame to file
if tmin <= h.t <= tmax:
filename=f"frame_{h.t:.2f}.png"
out_file=os.path.join(out,filename)
fig.write_image(out_file)
# Register the callback with NEURON
callback = h.beforestep_callback(cell.soma(0.5))
callback.set_callback(update_plot)
return fig, callback
Code: Select all
def plot_voltage_shape(folder,cell,max_shift):
# locations=load_geometry(folder)
voltages=load_voltages(folder)
ps = h.PlotShape(False)
vmin=min(max_shift)
vmax=max(max_shift)
ps.show(0)
ps.variable("v") # Associate the PlotShape with the 'v' variable
ps.scale(vmin, vmax) # Set the color scale
fig=ps.plot(plotly, cmap=cm.cool)
# Create a custom colormap using Matplotlib (cool colormap)
cmap = cm.cool
# Collect values of the variable from all segments
# Create a colormap function
colormap = cm.ScalarMappable(cmap=cmap, norm=mcolors.Normalize(vmin=0, vmax=1)).to_rgba
# Map the normalized values to a Plotly colorscale as strings
plotly_colorscale = [[v, f'rgb{tuple(int(255 * c) for c in colormap(v)[:3])}'] for v in np.linspace(0, 1, cmap.N)]
# Create a separate scatter plot for the colorbar
colorbar_trace = go.Scatter(
x=[0],
y=[0],
mode='markers',
marker=dict(
colorscale=plotly_colorscale,
cmin=vmin,
cmax=vmax,
colorbar=dict(
title="Max Shift",
thickness=20 # Adjust the thickness of the colorbar
),
showscale=True
)
)
# Add the colorbar trace to the figure
fig.add_trace(colorbar_trace)
fig.update_xaxes(showticklabels=False, showgrid=False)
fig.update_yaxes(showticklabels=False, showgrid=False)
fig.update_layout(
plot_bgcolor='rgba(0,0,0,0)'
)
fig.show()
def saveplot():
output_dir="frames"
out=os.path.join(folder,output_dir)
os.makedirs(out, exist_ok=True) # Create directory if it doesn't exist
file=os.path.join(out,f"pshape_t{t}.eps")
ps.printfile(file)
for i,t in enumerate(voltages["t"]):
v_values=voltages.iloc[i,1:]
index=0
for sec in cell.all:
for seg in sec:
seg.v=v_values[index]
index+=1
saveplot()
-
- Site Admin
- Posts: 6366
- Joined: Wed May 18, 2005 4:50 pm
- Location: Yale University School of Medicine
- Contact:
Re: voltage propagation in the whole cell
Well, you're on the right track, but this can be done without explicit, formal use of callbacks. And the resulting code could be easily understood by all, even those who are new to Python. Some of the following discussion is for the benefit of others who may read this thread but have less experience with Python and programming.
Think about what you are trying to produce: a series of images that show how the colors in a graph change over time. Imagine how this will be done, and then write an algorithm in pseudocode that describes the process. Example:
Assembling all those snapshots into a movie is a task that can be done with third party software after exiting from NEURON.
So now you have an algorithm and know how to
initialize a model: h.finitialize()
advance a simulation by a time step: h.fadvance()
or, if you prefer,
advance a simulation by multiple time steps: h.continuerun(h.t + DT) where DT is a whole number multiple of h.dt
I'd just use a PlotShape to create the false color plot of v (or whatever) over all the branches of a model cell. If NEURON's built-in InterViews renderings are too crude, you could try something else e.g. plotly
What else do you need to know? The following, which are quite ordinary Python tasks (not NEURON-specific), and examples of how to do them are all over the web:
how to grab and save a snapshot of a graph (well, this could be done with NEURON's built-in functions)
how to make sure that each snapshot has a unique name (preferably of the form basenamesequencenumber.extension) (I'd number each frame 0,1,2... instead of incorporating the actual time into the file name; you know what dt was)
how to assemble the snapshots into a "movie"
And there's probably more than one command line utility that can assemble a set of sequentially numbered images into a movie.
Think about what you are trying to produce: a series of images that show how the colors in a graph change over time. Imagine how this will be done, and then write an algorithm in pseudocode that describes the process. Example:
Code: Select all
initialize a model
grab and save a snapshot of a graph that shows a "false color plot" of how membrane potential varies over the model cell
repeat
advance the simulation by some time interval (one dt, or multiple dts, it's up to you)
grab and save another snapshot
until time is >= when you want to stop
So now you have an algorithm and know how to
initialize a model: h.finitialize()
advance a simulation by a time step: h.fadvance()
or, if you prefer,
advance a simulation by multiple time steps: h.continuerun(h.t + DT) where DT is a whole number multiple of h.dt
I'd just use a PlotShape to create the false color plot of v (or whatever) over all the branches of a model cell. If NEURON's built-in InterViews renderings are too crude, you could try something else e.g. plotly
Code: Select all
import plotly
. . .
ps = h.PlotShape(False)
ps.variable('v')
ps.plot(plotly, cmap=cm.cool).show()
how to grab and save a snapshot of a graph (well, this could be done with NEURON's built-in functions)
how to make sure that each snapshot has a unique name (preferably of the form basenamesequencenumber.extension) (I'd number each frame 0,1,2... instead of incorporating the actual time into the file name; you know what dt was)
how to assemble the snapshots into a "movie"
And there's probably more than one command line utility that can assemble a set of sequentially numbered images into a movie.