scipy equivalent for MATLAB spy - python

I have been porting code for an isomap algorithm from MATLAB to Python. I am trying to visualize the sparsity pattern using the spy function.
MATLAB command:
spy(sparse(A));
drawnow;
Python command:
matplotlib.pyplot.spy(scipy.sparse.csr_matrix(A))
plt.show()
I am not able to reproduce the MATLAB result in Python using the above command. Using the command with only A in non-sparse format gives quite similar result to MATLAB. But it's taking quite long (A being 2000-by-2000). What would be the MATLAB equivalent of a sparse function for scipy?

Maybe it's your version of matplotlib that makes trouble, as for me scipy.sparse and matplotlib.pylab work well together.
See sample code below that produces the 'spy' plot attached.
import matplotlib.pylab as plt
import scipy.sparse as sps
A = sps.rand(10000,10000, density=0.00001)
M = sps.csr_matrix(A)
plt.spy(M)
plt.show()
# Returns here '1.3.0'
matplotlib.__version__
This gives this plot:

I just released betterspy, which arguably does a better job here. Install with
pip install betterspy
and run with
import betterspy
from scipy import sparse
A = sparse.rand(20, 20, density=0.1)
betterspy.show(A)
betterspy.write_png("out.png", A)

With smaller markers:
import matplotlib.pylab as pl
import scipy.sparse as sps
import scipy.io
import sys
A=scipy.io.mmread(sys.argv[1])
pl.spy(A,precision=0.01, markersize=1)
pl.show()

Related

Why doesn't this scipy fourier integration function work?

When I try to integrate a periodic array with the scipy function sp.fftpack.diff(x,order=-1), it sometimes works and sometimes doesn't.
For example, when integrating x=sin(alpha) to obtain an array of the values of the integral when evaluated from 0 to discrete values up to 2*pi I get the expected result -cos(\alphas). However, when I use it to calculate the values of the integrals of x=sin(alpha)+cos(alpha)+1 in the same ranges I do not get the right answer, even when the function is periodic.
I do not understand how this function works. Does someone have an idea?
https://docs.scipy.org/doc/scipy/reference/generated/scipy.fftpack.diff.html
For example, with this code I obtain the results in the image,I am also comparing the results with the obtained by the trapezoidal rule, which does work when fixing the offset.enter image description here
import numpy as np
from scipy import fftpack as sp
from scipy import integrate as inte
import matplotlib.pyplot as plt
N=150
h=(2*np.pi)/N
x=np.arange(-np.pi,np.pi,h)
y=np.sin(x)+np.cos(x)+1
arrExact=-np.cos(x)+np.sin(x)+x
st=inte.cumtrapz(y,x,initial=0)-2.1
di=sp.diff(y, order=-1)-1
plt.plot(x,di,label='diff')
plt.plot(x,arrExact,label='Exact')
plt.plot(x,st,label='cumpTrapz')
plt.legend()
plt.show()
Edit: Well, reading again I realized scipy assumes x[0]=0, however I need to integrate spectrally arrays that do not satisfies this condition, How can I proceed?

DeprecationWarning rasied in Spyder for every Scipy function used

I'm coding in Spyder and the code runs, but every line that uses sp.___ raises a DeprecationWarning, e.g. DeprecationWarning: scipy.array is deprecated and will be removed in SciPy 2.0.0, use numpy.array instead.
Why is Spyder doing this and how do I allow me to use scipy without raising this error? Failing that, what can I do to suppress the error from popping up each time?
The code is like this:
import matplotlib.pyplot as plt,scipy as sp
import scipy.optimize as op
a=9.3779
x_in=sp.array([.095,.065,.09,.108,.125,.115,.040,.055,.055])
x=(x_in+14)
y_in=sp.array([.2,.6,.5,.4,.1,.3,-0.2,-0.4,0])
y=y_in+45
ax.plot(x_in,y_in,'ro')
plt.show()
This raises the error:
C:\Users\Shiva Pingle\Desktop\python\others\peaks.py:38: DeprecationWarning: scipy.array is deprecated and will be removed in SciPy 2.0.0, use numpy.array instead
x_in=sp.array([.095,.065,.09,.108,.125,.115,.040,.055,.055])
C:\Users\Shiva Pingle\Desktop\python\others\peaks.py:40: DeprecationWarning: scipy.array is deprecated and will be removed in SciPy 2.0.0, use numpy.array instead
y_in=sp.array([.2,.6,.5,.4,.1,.3,-0.2,-0.4,0])
Your solution in the comments will make you ignore all the deprecation warnings. This is not suggested.
You could instead import numpy as np and use the np.array().
Corrected code:
import matplotlib.pyplot as plt,scipy as sp
import scipy.optimize as op
import numpy as np # Added import of numpy
a=9.3779
x_in=np.array([.095,.065,.09,.108,.125,.115,.040,.055,.055]) # Changed sp to np
x=(x_in+14)
y_in=np.array([.2,.6,.5,.4,.1,.3,-0.2,-0.4,0]) # Changed sp to np
y=y_in+45
plt.plot(x_in,y_in,'ro') # Also changed the ax to plt
plt.show()

Resampling does not work as expected (see plot)

I was trying to understand what exactly scipy.signal.resample is to do. Here is a simple code:
import numpy as np
from scipy.signal import resample
import matplotlib.pyplot as plt
t=np.linspace(1,4,10)
x=t
x_resampled=resample(x,10000)
plt.plot(x)
plt.figure()
plt.plot(x_resampled)
the input is
and the output of code is
however, I expected
Can you please tell me how can I settle scipy.signal.resample to obtain such a result?
Look at the documentation for resample (emphasis mine):
Because a Fourier method is used, the signal is assumed to be periodic.
On the non-periodic data you're using the above assumption doesn't hold. So a valid result should not be expected.

Why is numdifftools so inaccurate? How does it work?

I'm using python's numdifftools library to perform derivatives. However, a few tests prove the library is highly inaccurate:
import numpy as np
from numdifftools import Derivative
# Result should be 1/2 or 0.5
Derivative(np.log, 1)(2.0)
>>> array(0.5493061443340549)
Is there a way to fix this inaccuracy?
Using numdifftools 0.9.16 and numpy 1.9.3 the following code gives an exact result:
import numpy as np
from numdifftools import Derivative
# Result should be 1/2 or 0.5
Derivative(np.log)(2.0)
Output:
array(0.5000000000000238)
Issue spotted.
Derivative(np.log, 1)(2.0)
gives the wrong answer. The n should be explicitly stated:
Derivative(np.log, n=1)(2.0)
>>> array(0.5000000000000234)

Pandas plot doesn't show

When using this in a script (not IPython), nothing happens, i.e. the plot window doesn't appear :
import numpy as np
import pandas as pd
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts.plot()
Even when adding time.sleep(5), there is still nothing. Why?
Is there a way to do it, without having to manually call matplotlib ?
Once you have made your plot, you need to tell matplotlib to show it. The usual way to do things is to import matplotlib.pyplot and call show from there:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts.plot()
plt.show()
In older versions of pandas, you were able to find a backdoor to matplotlib, as in the example below. NOTE: This no longer works in modern versions of pandas, and I still recommend importing matplotlib separately, as in the example above.
import numpy as np
import pandas as pd
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts.plot()
pd.tseries.plotting.pylab.show()
But all you are doing there is finding somewhere that matplotlib has been imported in pandas, and calling the same show function from there.
Are you trying to avoid calling matplotlib in an effort to speed things up? If so then you are really not speeding anything up, since pandas already imports pyplot:
python -mtimeit -s 'import pandas as pd'
100000000 loops, best of 3: 0.0122 usec per loop
python -mtimeit -s 'import pandas as pd; import matplotlib.pyplot as plt'
100000000 loops, best of 3: 0.0125 usec per loop
Finally, the reason the example you linked in comments doesn't need the call to matplotlib is because it is being run interactively in an iPython notebook, not in a script.
In case you are using matplotlib, and still, things don't show up in iPython notebook (or Jupyter Lab as well) remember to set the inline option for matplotlib in the notebook.
import matplotlib.pyplot as plt
%matplotlib inline
Then the following code will work flawlessly:
fig, ax = plt.subplots(figsize=(16,9));
change_per_ins.plot(ax=ax, kind='hist')
If you don't set the inline option it won't show up and by adding a plt.show() in the end you will get duplicate outputs.
I did just
import matplotlib.pyplot as plt
%matplotlib inline
and add line
plt.show()
next to df.plot() and it worked well for
The other answers involve importing matplotlib.pyplot and/or calling some second function manually.
Instead, you can configure matplotlib to be in interactive mode with its configuration files.
Simply add the line
interactive: True
to a file called matplotlibrc in one of the following places:
In the current working directory
In the platform specific user directory specified by matplotlib.get_configdir()
On unix-like system, typically /home/username/.config/matplotlib/
On Windows C:\\Documents and Settings\\username\\.matplotlib\\

Categories

Resources