def sos_zplane(sos,auto_scale=True,size=<NUM_LIT:2>,tol = <NUM_LIT>):
Ns,Mcol = sos.shape<EOL>N_roots = []<EOL>for k in range(Ns):<EOL><INDENT>N_roots_tmp = np.roots(sos[k,:<NUM_LIT:3>])<EOL>if N_roots_tmp[<NUM_LIT:1>] == <NUM_LIT:0.>:<EOL><INDENT>N_roots = np.hstack((N_roots,N_roots_tmp[<NUM_LIT:0>]))<EOL><DEDENT>else:<EOL><INDENT>N_roots = np.hstack((N_roots,N_roots_tmp))<EOL><DEDENT><DEDENT>D_roots = []<EOL>for k in range(Ns):<EOL><INDENT>D_roots_tmp = np.roots(sos[k,<NUM_LIT:3>:])<EOL>if D_roots_tmp[<NUM_LIT:1>] == <NUM_LIT:0.>:<EOL><INDENT>D_roots = np.hstack((D_roots,D_roots_tmp[<NUM_LIT:0>]))<EOL><DEDENT>else:<EOL><INDENT>D_roots = np.hstack((D_roots,D_roots_tmp))<EOL><DEDENT><DEDENT>x_scale = <NUM_LIT>*size<EOL>y_scale = <NUM_LIT>*size   <EOL>x_off = <NUM_LIT><EOL>y_off = <NUM_LIT><EOL>M = len(N_roots)<EOL>N = len(D_roots)<EOL>if auto_scale:<EOL><INDENT>if M > <NUM_LIT:0> and N > <NUM_LIT:0>:<EOL><INDENT>size = max(np.max(np.abs(N_roots)),np.max(np.abs(D_roots)))+<NUM_LIT><EOL><DEDENT>elif M > <NUM_LIT:0>:<EOL><INDENT>size = max(np.max(np.abs(N_roots)),<NUM_LIT:1.0>)+<NUM_LIT><EOL><DEDENT>elif N > <NUM_LIT:0>:<EOL><INDENT>size = max(<NUM_LIT:1.0>,np.max(np.abs(D_roots)))+<NUM_LIT><EOL><DEDENT>else:<EOL><INDENT>size = <NUM_LIT><EOL><DEDENT><DEDENT>plt.figure(figsize=(<NUM_LIT:5>,<NUM_LIT:5>))<EOL>plt.axis('<STR_LIT>')<EOL>r = np.linspace(<NUM_LIT:0>,<NUM_LIT:2>*np.pi,<NUM_LIT:200>)<EOL>plt.plot(np.cos(r),np.sin(r),'<STR_LIT>')<EOL>plt.plot([-size,size],[<NUM_LIT:0>,<NUM_LIT:0>],'<STR_LIT>')<EOL>plt.plot([<NUM_LIT:0>,<NUM_LIT:0>],[-size,size],'<STR_LIT>')<EOL>if M > <NUM_LIT:0>:<EOL><INDENT>N_uniq, N_mult=unique_cpx_roots(N_roots,tol=tol)<EOL>plt.plot(np.real(N_uniq),np.imag(N_uniq),'<STR_LIT>',mfc='<STR_LIT:None>',ms=<NUM_LIT:8>)<EOL>idx_N_mult = np.nonzero(np.ravel(N_mult><NUM_LIT:1>))[<NUM_LIT:0>]<EOL>for k in range(len(idx_N_mult)):<EOL><INDENT>x_loc = np.real(N_uniq[idx_N_mult[k]]) + x_off*x_scale<EOL>y_loc =np.imag(N_uniq[idx_N_mult[k]]) + y_off*y_scale<EOL>plt.text(x_loc,y_loc,str(N_mult[idx_N_mult[k]]),<EOL>ha='<STR_LIT>',va='<STR_LIT>',fontsize=<NUM_LIT:10>)<EOL><DEDENT><DEDENT>if N > <NUM_LIT:0>:<EOL><INDENT>D_uniq, D_mult=unique_cpx_roots(D_roots,tol=tol)<EOL>plt.plot(np.real(D_uniq),np.imag(D_uniq),'<STR_LIT>',ms=<NUM_LIT:8>)<EOL>idx_D_mult = np.nonzero(np.ravel(D_mult><NUM_LIT:1>))[<NUM_LIT:0>]<EOL>for k in range(len(idx_D_mult)):<EOL><INDENT>x_loc = np.real(D_uniq[idx_D_mult[k]]) + x_off*x_scale<EOL>y_loc =np.imag(D_uniq[idx_D_mult[k]]) + y_off*y_scale<EOL>plt.text(x_loc,y_loc,str(D_mult[idx_D_mult[k]]),<EOL>ha='<STR_LIT>',va='<STR_LIT>',fontsize=<NUM_LIT:10>)            <EOL><DEDENT><DEDENT>if M - N < <NUM_LIT:0>:<EOL><INDENT>plt.plot(<NUM_LIT:0.0>,<NUM_LIT:0.0>,'<STR_LIT>',mfc='<STR_LIT:None>',ms=<NUM_LIT:8>)<EOL><DEDENT>elif M - N > <NUM_LIT:0>:<EOL><INDENT>plt.plot(<NUM_LIT:0.0>,<NUM_LIT:0.0>,'<STR_LIT>',ms=<NUM_LIT:8>)<EOL><DEDENT>if abs(M - N) > <NUM_LIT:1>:<EOL><INDENT>plt.text(x_off*x_scale,y_off*y_scale,str(abs(M-N)),<EOL>ha='<STR_LIT>',va='<STR_LIT>',fontsize=<NUM_LIT:10>)        <EOL><DEDENT>plt.xlabel('<STR_LIT>')<EOL>plt.ylabel('<STR_LIT>')<EOL>plt.title('<STR_LIT>')<EOL>plt.axis([-size,size,-size,size])<EOL>return M,N<EOL>
Create an z-plane pole-zero plot.

Create an z-plane pole-zero plot using the numerator
and denominator z-domain system function coefficient
ndarrays b and a respectively. Assume descending powers of z.

Parameters
----------
sos : ndarray of the sos coefficients
auto_scale : bool (default True)
size : plot radius maximum when scale = False

Returns
-------
(M,N) : tuple of zero and pole counts + plot window

Notes
-----
This function tries to identify repeated poles and zeros and will 
place the multiplicity number above and to the right of the pole or zero.
The difficulty is setting the tolerance for this detection. Currently it
is set at 1e-3 via the function signal.unique_roots.

Examples
--------
>>> # Here the plot is generated using auto_scale
>>> sos_zplane(sos)
>>> # Here the plot is generated using manual scaling
>>> sos_zplane(sos,False,1.5)