<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Sorting Network Sets
Frequently a set of Networks is recorded while changing some other variable; like voltage, or current or time. So... now you have this set of data  and you want to look at how some feature evolves, or calculate some representative  statics. This example demonstrates how to do this using NetworkSets.
Generate some Data
For the purpose of this example we use a predefined skrf.Media object to generate some networks, and save them as a series of touchstone files. Each  file is named with a timestamp, generated with the convenience function rf.now_string().
Step1:  Lets take a look at what we made
Step2:  Not sorted (default)
When created using NetworkSet.from_dir(), the NetworkSet's stores each Network randomly
Step3:  Sort it
Step4:  Sorting using key argument
You can also pass a function through the key argument, which allows you to sort on arbitrary properties. For example, we could sort based on the sub-second field of the name,
Step5:  Extracting Datetimes
You can also convert the ntwk names to datetime objects, in case you want to plot something with pandas or do some other processing. There is a companion function to rf.now_string() which is rf.now_string_2_dt(). How creative..
Step6:  Put into a Pandas DataFrame and Plot
The next step is to slice the network set along the time axis. For example we may want to look at S11 phase, at a few different frequencies. This can be done with the following script. Note that NetworkSets can be sliced by frequency with human readable strings, just like Networks.
Step7:  Visualizing Behavoir with  signature
It may be of use to visualize the evolution of a scalar component of the network set over all frequencies. This can be done with a little bit of array manipulation and imshow. For example if we take the magnitude in dB for each network, and create  2D matrix from this,
Step8:  This array has shape  ( 'Number of Networks' , 'Number frequency points'). This can be visualized with imshow. Most of the code below just adds labels, and axis-scales.
Step9:  This process is automated with the method NetworkSet.signature(). It even has a vs_time parameter which will automatically create the DateTime index from the Network's names, if they were written by rf.now_string()
<ASSISTANT_TASK:>
Python Code:
from time import sleep 
import skrf as rf 
%matplotlib inline
from pylab import * 
rf.stylely()
!rm -rf tmp
!mkdir tmp
wg = rf.wr10 # just a dummy media object to generate data
wg.frequency.npoints = 101
for k in range(10):
    # timestamp generated with `rf.now_string()`
    ntwk = wg.random(name=rf.now_string()+'.s1p')
    ntwk.s = k*ntwk.s
    ntwk.write_touchstone(dir='tmp')
    sleep(.1)
Explanation: Sorting Network Sets
Frequently a set of Networks is recorded while changing some other variable; like voltage, or current or time. So... now you have this set of data  and you want to look at how some feature evolves, or calculate some representative  statics. This example demonstrates how to do this using NetworkSets.
Generate some Data
For the purpose of this example we use a predefined skrf.Media object to generate some networks, and save them as a series of touchstone files. Each  file is named with a timestamp, generated with the convenience function rf.now_string().
End of explanation
ls tmp
Explanation: Lets take a look at what we made
End of explanation
ns = rf.NS.from_dir('tmp')
ns.ntwk_set 
Explanation: Not sorted (default)
When created using NetworkSet.from_dir(), the NetworkSet's stores each Network randomly
End of explanation
ns.sort()
ns.ntwk_set
Explanation: Sort it
End of explanation
ns = rf.NetworkSet.from_dir('tmp')
ns.sort(key = lambda x: x.name.split('.')[0])
ns.ntwk_set
Explanation: Sorting using key argument
You can also pass a function through the key argument, which allows you to sort on arbitrary properties. For example, we could sort based on the sub-second field of the name,
End of explanation
ns.sort()
dt_idx = [rf.now_string_2_dt(k.name ) for k in ns]
dt_idx
Explanation: Extracting Datetimes
You can also convert the ntwk names to datetime objects, in case you want to plot something with pandas or do some other processing. There is a companion function to rf.now_string() which is rf.now_string_2_dt(). How creative..
End of explanation
import pandas as pd 
dates = pd.DatetimeIndex(dt_idx)
# create a function to pull out S11 in degrees at a specific frequency
s_deg_at = lambda s:{s: [k[s].s_deg[0,0,0] for k in ns]}
for f in ['80ghz', '90ghz','100ghz']:
    df =pd.DataFrame(s_deg_at(f), index=dates)
    df.plot(ax=gca())
title('Phase Evolution in Time')
ylabel('S11 (deg)')
Explanation: Put into a Pandas DataFrame and Plot
The next step is to slice the network set along the time axis. For example we may want to look at S11 phase, at a few different frequencies. This can be done with the following script. Note that NetworkSets can be sliced by frequency with human readable strings, just like Networks.
End of explanation
mat = array([k.s_db.flatten() for k in ns])
mat.shape
Explanation: Visualizing Behavoir with  signature
It may be of use to visualize the evolution of a scalar component of the network set over all frequencies. This can be done with a little bit of array manipulation and imshow. For example if we take the magnitude in dB for each network, and create  2D matrix from this,
End of explanation
freq = ns[0].frequency
# creates x and y scales
extent = [freq.f_scaled[0], freq.f_scaled[-1], len(ns) ,0]
#make the image
imshow(mat, aspect='auto',extent=extent,interpolation='nearest')
# label things
grid(0)
freq.labelXAxis()
ylabel('Network #')
cbar = colorbar()
cbar.set_label('Magntidue (dB)')
Explanation: This array has shape  ( 'Number of Networks' , 'Number frequency points'). This can be visualized with imshow. Most of the code below just adds labels, and axis-scales.
End of explanation
ns.signature(component='s_db', vs_time=True,cbar_label='Magnitude (dB)')
Explanation: This process is automated with the method NetworkSet.signature(). It even has a vs_time parameter which will automatically create the DateTime index from the Network's names, if they were written by rf.now_string()
End of explanation
<END_TASK>