Using spy() in Julia - matplotlib

I am trying to use spy(). But I am not getting the use of it right. I think my error has something to do with this: https://github.com/JuliaLang/julia/issues/2121
I have a 300x300 Array{Float64,2}
using PyPlot
pygui(true)
spy(I) # where I is my 300x300 array
and it gives me this error:
LoadError: PyError (:PyObject_Call) <type 'exceptions.TypeError'>
TypeError("object of type 'PyCall.jlwrap' has no len()",)
File "/home/ashley/.julia/v0.4/Conda/deps/usr/lib/python2.7/site-packages/matplotlib/pyplot.py", line 3154, in plot
ret = ax.plot(*args, **kwargs)
File "/home/ashley/.julia/v0.4/Conda/deps/usr/lib/python2.7/site-packages/mpl_toolkits/mplot3d/axes3d.py", line 1539, in plot
zs = np.ones(len(xs)) * zs
I have tried specifying spy(I, zs=zeros(size(I)) but then I just get the error:
LoadError: ArgumentError: function spy does not accept keyword arguments
while loading In[260], in expression starting on line 13
Any ideas?

spy shows the non-zero elements. Apparently it doesn't show anything if there are no non-zero elements.
M = sprand(300, 300, 0.1) # generate a sparse matrix with density 0.1 of non-zeros
M = full(M)
spy(M)
works for me.

Related

My plt animation doesn't work: "'NoneType' object has no attribute 'canvas'"

I'm trying to simulate the segregation process in a city for a school project. I've managed to plot the city when initialized and after segregation, but I don't manage to create the animation showing the city's inhabitants moving to show the evolution.
I have two methods in my Ville class (I'm coding in French) that should make the animation together.
def afficher(self, inclure_satisfaction=False, inclure_carte_categories=False, size=5):
carte = self.carte_categories(inclure_satisfaction=inclure_satisfaction)
if inclure_carte_categories:
print("Voici la carte des catégories (à titre de vérification)")
print(carte)
mat_rs = masked_array(carte, carte!=1.5)
mat_ri = masked_array(carte, carte!=1)
mat_bs = masked_array(carte, carte!=2.5)
mat_bi = masked_array(carte, carte!=2)
plt.figure(figsize=(size, size))
affichage_rs = plt.imshow(mat_rs, cmap=cmap_rs)
affichage_ri = plt.imshow(mat_ri, cmap=cmap_ri)
affichage_bs = plt.imshow(mat_bs, cmap=cmap_bs)
affichage_bi = plt.imshow(mat_bi, cmap=cmap_bi)
return plt.figure()
(this function plot the map by first getting an array from the method carte_categories in function of the category of each inhabitant and then getting an array for each value to plot)
def resoudre2(self):
fig = plt.figure(figsize=(5,5))
list_of_artists = []
while self.habitants_insatisfaits != []:
self.demenagement_insatisfait_aleatoire()
list_of_artists.append([self.afficher(inclure_satisfaction=True)])
ani = ArtistAnimation(fig, list_of_artists, interval=200, blit=True)
return ani
(habitants_insatisfaits is a list that contains the "insatisfied inhabitants": there are two few people of their category around them, so they want to move somewhere else; so resoudre means solve, and this function loops until all the inhabitants are satisfied where they are (and this way the society is mechanically segregated)
The initialized city looks like this initialized city (dark colors for insatisfied inhabitants), and the segregated city looks like that segregated city.
But when I enter
a = ville1.resoudre2(compter=True)
I don't get an animation but only this error message:
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:211: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:206: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).
Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/matplotlib/cbook/__init__.py", line 196, in process
func(*args, **kwargs)
File "/usr/local/lib/python3.7/dist-packages/matplotlib/animation.py", line 951, in _start
self._init_draw()
File "/usr/local/lib/python3.7/dist-packages/matplotlib/animation.py", line 1533, in _init_draw
fig.canvas.draw_idle()
AttributeError: 'NoneType' object has no attribute 'canvas'
/usr/local/lib/python3.7/dist-packages/matplotlib/image.py:452: UserWarning: Warning: converting a masked element to nan.
dv = np.float64(self.norm.vmax) - np.float64(self.norm.vmin)
/usr/local/lib/python3.7/dist-packages/matplotlib/image.py:459: UserWarning: Warning: converting a masked element to nan.
a_min = np.float64(newmin)
/usr/local/lib/python3.7/dist-packages/matplotlib/image.py:464: UserWarning: Warning: converting a masked element to nan.
a_max = np.float64(newmax)
<string>:6: UserWarning: Warning: converting a masked element to nan.
/usr/local/lib/python3.7/dist-packages/matplotlib/colors.py:993: UserWarning: Warning: converting a masked element to nan.
data = np.asarray(value)
(first problem) and then every map (corresponding to each step of the segregating city) is plotted (second problem; see here). And when I try to type
print(a)
from IPython.display import HTML
HTML(a.to_html5_video())
to plot the animation, I only get
<matplotlib.animation.ArtistAnimation object at 0x7f4cd376bfd0>
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-20-d7ca1fcdadb6> in <module>()
1 print(a)
2 from IPython.display import HTML
----> 3 HTML(a.to_html5_video())
2 frames
/usr/local/lib/python3.7/dist-packages/matplotlib/animation.py in _init_draw(self)
1531 # Flush the needed figures
1532 for fig in figs:
-> 1533 fig.canvas.draw_idle()
1534
1535 def _pre_draw(self, framedata, blit):
AttributeError: 'NoneType' object has no attribute 'canvas'
So I don't understand why I get this error and not just my animation...
Thank you for your help, it's the first time I ask questions here so don't hesitate if you need more details about my code! :)
Nathan
Had the same issue, downgrading Matplotlib fixed the issue for me.
pip install matplotlib==3.5.1

why would a line of code work when evaluated, but not when run

I have passed a DataFrame from an ipython notebook to a function inside a standard .py file.
In the function, i'm using df['column_name'].values to try to extract all the values from that column.
While debugging (in pycharm), I am running this line in the 'evaluate' tool pycharm provides and it works fine. However, when I run the same line normally (outside the tool window), i get an error:
"TypeError: list indices must be integers or slices, not str"
When looking at my dataframe in the workspace variables section, it is interpreted correctly as a dataframe.
The dataframe object I am passing has 3 columns ('x','y' and 'likelyhood'), each containing integers/floats. The line in question that unpacks the values inside one of these columns is the first line of the function.
Can anyone explain how this can happen? What is the difference that causes the fact that a line of code can work in one, and return an error in the other?
and also what might cause this specific TypeError and how can I solve this bug?
the data frame as printed by df.tail(10):
coords x y likelihood
105570 297.497525 332.355521 1.0
105571 297.463208 332.353797 1.0
105572 297.439774 332.383908 1.0
105573 297.457581 332.458205 1.0
105574 297.487260 332.402202 1.0
105575 297.519772 332.451551 1.0
105576 297.495998 332.431064 1.0
105577 297.516722 332.113481 1.0
105578 297.542539 332.080923 1.0
105579 297.528317 332.046282 1.0
full function:
import math
import numpy as np
import pandas as pd
def filter_jumps(bp, thresh=10):
"""
the function watches for jumps that cannot happen, and interpolates the location of the point acoordingly
"""
x=bp['x'].values
y=bp['y'].values
for i in range(1,len(x)):
if np.abs(x[i]+y[i]-x[i-1]-y[i-1]) > thresh:
start = i-1; end = None; idx=i+1
while not end:
if np.abs(x[idx]+y[idx]-x[idx-1]-y[idx-1]) > thresh:
end = idx
else:
idx += 1
rang = end-start
x[start:end] = np.linspace(x[start], x[end], rang)
y[start:end] = np.linspace(y[start], y[end], rang)
bp['x'] = x
bp['y'] = y
return bp

DataFrame.apply(func, raw=True) doesn't seem to take effect?

I am trying to hash together only a few columns of my dataframe df so I do
temp = df['field1', 'field2']
df["hash"] = temp.apply(lambda x: hash(x), raw=True, axis=1)
I set raw to true because the doc (I am using 0.22) says it will pass a numpy array instead of a mutable Series but even with raw=True I am getting a Series, why?
File "/nix/store/9ampki9dbq0imhhm7i27qkh56788cjpz-python3.6-pandas-0.22.0/lib/python3.6/site-packages/pandas/core/frame.py", line 4877, in apply
ignore_failures=ignore_failures)
File "/nix/store/9ampki9dbq0imhhm7i27qkh56788cjpz-python3.6-pandas-0.22.0/lib/python3.6/site-packages/pandas/core/frame.py", line 4973, in _apply_standard
results[i] = func(v)
File "/home/teto/mptcpanalyzer/mptcpanalyzer/data.py", line 190, in _hash_row
return hash(x)
File "/nix/store/9ampki9dbq0imhhm7i27qkh56788cjpz-python3.6-pandas-0.22.0/lib/python3.6/site-packages/pandas/core/generic.py", line 1045, in __hash__
' hashed'.format(self.__class__.__name__))
TypeError: ("'Series' objects are mutable, thus they cannot be hashed", 'occurred at index 1')
It's strange, as I can't reproduce your exact error (that is, by me, raw=True indeed results in an np.ndarray being passed). In any case, neither a Series nor a np.ndarray are hashable. The following works, though:
temp.apply(lambda x: hash(tuple(x)), axis=1)
A tuple is hashable.

PyPlot throws an error when DataFrame-Column has missing values

I have the following problem:
I would like to plot a variable from a Dataframe with missing values, which are denoted as "NA". However, if I just go ahead and use with Pyplot
x = df[df[:country] .== "Belgium",:year]
y = df[df[:country] .== "Belgium",:hpNormLog]
plot(x, y, "b-", linewidth=2)
I get the following error message:
PyError (:PyObject_Call) <class 'TypeError'> TypeError("float() argument must be a string or a number, not 'PyCall.jlwrap'",)
File "C:\Anaconda3\lib\site-packages\matplotlib\pyplot.py", line 3154, in plot
ret = ax.plot(*args, **kwargs) File "C:\Anaconda3\lib\site-packages\matplotlib\__init__.py", line 1811, in inner
return func(ax, *args, **kwargs) File "C:\Anaconda3\lib\site-packages\matplotlib\axes\_axes.py", line 1425, in plot
self.add_line(line) File "C:\Anaconda3\lib\site-packages\matplotlib\axes\_base.py", line 1708, in add_line
self._update_line_limits(line) File "C:\Anaconda3\lib\site-packages\matplotlib\axes\_base.py", line 1730, in _update_line_limits
path = line.get_path() File "C:\Anaconda3\lib\site-packages\matplotlib\lines.py", line 925, in get_path
self.recache() File "C:\Anaconda3\lib\site-packages\matplotlib\lines.py", line 621, in recache
y = np.asarray(yconv, np.float_) File "C:\Anaconda3\lib\site-packages\numpy\core\numeri...
I would be very grateful, if I had a solution around it.
Best,
Ilja
I found the following solution. I am not deep enough into how Julia works, so I can only say what works and what does not. Arrays with NaN can be plotted with the code written above, columns of DataFrames however do not permit the same thing. The column needs to be converted to an Array, before it can be plotted with missing values. The following code solves the problem:
x = df[df[:country] .== "Belgium",:year]
ytest = df[df[:country] .== "Belgium",:hpNormLog]
y = convert(Array,ytest,NaN)
plot(x, y, "b-", linewidth=2)
x does not contain missing values and therefore I can keep using the DataFrame, but y does contain missing values, so it needs to be converted to an Array. The third argument of convert specifies to what missing values should be converted, in this case to NaN.
Why don't you perform error-handling?
try:
plot(x, y, "b-", linewidth=2)
except PyError:
pass
Escape the error when it works most of the time for your input but skip plotting of "NA"-values....

Julia PyPlot can't create quadratic function

I'm trying to learn to plot things with Julia using PyPlot, and I tried to plot a quadratic function. It does not like how I'm squaring x. I tried using x**2 and x*x, and the compiler did not accept those either. What should I be using to square x?
Thanks
Code # line 7:
x1 = linspace(0,4*pi, 500); y1 = x^2
Error:
LoadError: MethodError: `*` has no method matching *(::LinSpace{Float64},
::LinSpace{Float64})
Closest candidates are:
*(::Any, ::Any, !Matched::Any, !Matched::Any...)
*{T}(!Matched::Bidiagonal{T}, ::AbstractArray{T,1})
*(!Matched::Number, ::AbstractArray{T,N})
...
in power_by_squaring at intfuncs.jl:80
in ^ at intfuncs.jl:108
in include_string at loading.jl:282
in include_string at C:\Users\User\.julia\v0.4\CodeTools\src\eval.jl:32
in anonymous at C:\Users\User\.julia\v0.4\Atom\src\eval.jl:84
in withpath at C:\Users\User\.julia\v0.4\Requires\src\require.jl:37
in withpath at C:\Users\User\.julia\v0.4\Atom\src\eval.jl:53
[inlined code] from C:\Users\User\.julia\v0.4\Atom\src\eval.jl:83
in anonymous at task.jl:58
while loading C:\Users\User\Desktop\Comp Sci\Class\plotTest, in expression
starting on line 7
To square every element of an array, use x.^2.
You are trying to square all of the elements of an array. This means you need to use the element-wise version x.^2.