What does
if self.transforms:
data = self.transforms(data)
do? I don't understand the logic behind this line - what is the condition the line is using?
I'm reading an article on creating a custom dataset with pytorch based on the below implementation:
#custom dataset
class MNISTDataset(Dataset):
def __init__(self, images, labels=None, transforms=None):
self.X = images
self.y = labels
self.transforms = transforms
def __len__(self):
return (len(self.X))
def __getitem__(self, i):
data = self.X.iloc[i, :]
data = np.asarray(data).astype(np.uint8).reshape(28, 28, 1)
if self.transforms:
data = self.transforms(data)
if self.y is not None:
return (data, self.y[i])
else:
return data
train_data = MNISTDataset(train_images, train_labels, transform)
test_data = MNISTDataset(test_images, test_labels, transform)
# dataloaders
trainloader = DataLoader(train_data, batch_size=128, shuffle=True)
testloader = DataLoader(test_data, batch_size=128, shuffle=True)
thank you! i'm basically trying to understand why it works & how it applies transforms to the data.
The dataset MNISTDataset can optionnaly be initialized with a transform function. If such transform function is given it be saved in self.transforms else it will keep its default values None. When calling a new item with __getitem__, it first checks if the transform is a truthy value, in this case it checks if self.transforms can be coerced to True which is the case for a callable object. Otherwise it means self.transforms hasn't been provided in the first place and no transform function is applied on data.
Here's a general example, out of a torch/torchvision context:
def do(x, callback=None):
if callback: # will be True if callback is a function/lambda
return callback(x)
return x
do(2) # returns 2
do(2, callback=lambda x: 2*x) # returns 4
I am implementing a big circle class,which does operations like computes area,compares two circle,compares a circle and square etc,but i am having trouble with this small snippet.
class Circle(Point):
def __init__(self, x=0, y=0, r=0):
self.X = x
self.Y = y
self.R = r
self.area = math.pi*r*r
def __str__(self):
return ("A Circle which has centre at " + "(" + "%0.6f" % (self.X) + ", "
+ "%0.6f" % (self.Y) + ")" + "and its radius " + "%0.6f" % (self.R))
def getX(self):
return self.X
def getY(self):
return self.Y
def getR(self):
return self.R
def setR(self):
pass
def area(self):
return math.pi * self.R * self.R
def main():
x = float(input("Enter x coordinate of first circle's centre: "))
y = float(input("Enter y coordinate of the first circle's centre: "))
r = float(input("Enter first circle's radius: "))
pointx1 = x
pointy1 = y
radius1 = r
first_circle = Circle(x, y, r)
print(first_circle)
print("\nArea of first circle is %0.6f" % (first_circle, first_circle.area())
main()
However i get the following error on executing the below code:
print("\nArea of first circle is %0.6f" % (first_circle, first_circle.area))
TypeError: float argument required, not instance
How do i get rid of this.I have calculated self.area in constructor as because i am using it later(haven't shown the code here) to compare two circle's areas which are being sent as argument.Please help.
Remove the first argument in your string format:
print("\nArea of first circle is %0.6f" % (first_circle.area()))
I'm not sure why you put first_circle as an argument since %0.6f is the only part of the string requiring an argument.
Also you need to either rename self.area or rename the method area() because it causes conflicts if they have the same name.
I am new to matplotlib animation and am trying to animate a scatter plot where points moving towards the right will turn red gradually while points moving towards the left will turn blue gradually. The code doesn't work perfectly as it doesn't change the color of the points gradually. When I pause the animation and maximize it, the gradual change in color suddenly appears, when I play it, it is again the same. Here is the animation link. The final image should be something like this:
But the animation doesn't show gradual change of colors as you can see in the video.
Here is the code, I'd really appreciate your help. Thanks
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
import pandas as pd
class AnimatedScatter(object):
"""An animated scatter plot using matplotlib.animations.FuncAnimation."""
def __init__(self, numpoints=5):
self.numpoints = numpoints
self.stream = self.data_stream()
# Setup the figure and axes...
self.fig, self.ax = plt.subplots()
# Then setup FuncAnimation.
self.ani = animation.FuncAnimation(self.fig, self.update, interval=500,
init_func=self.setup_plot, blit=True,repeat=False)
self.fig.canvas.mpl_connect('button_press_event',self.onClick)
#self.ani.save("animation.mp4")
def setup_plot(self):
"""Initial drawing of the scatter plot."""
t=next(self.stream)
x, y, c = t[:,0],t[:,1],t[:,2]
self.scat = self.ax.scatter(x, y, c=c, s=50, animated=True)
self.ax.axis([-15, 15, -10, 10])
# For FuncAnimation's sake, we need to return the artist we'll be using
# Note that it expects a sequence of artists, thus the trailing comma.
return self.scat,
def data_stream(self):
#f=pd.read_csv("crc_viz.csv")
columns = ['TbyN','CbyS']
#f=f[['TbyN','CbyS']]
index=range(1,self.numpoints+1)
x=10*(np.ones((self.numpoints,1))-2*np.random.random((self.numpoints,1)))
y = 5*(np.ones((self.numpoints,1))-2*np.random.random((self.numpoints,1)))
f=np.column_stack((x,y))
f=pd.DataFrame(f,columns=columns)
print f
f['new_cbys'] = f['CbyS']
f['new_cbys'][f['new_cbys']<0] = -1
f['new_cbys'][f['new_cbys']>0] = 1
f=f[:self.numpoints]
cbys=np.array(list(f['CbyS']))
sign = np.array(list(f['new_cbys']))
x = np.array([0]*self.numpoints)
y = np.array(f['TbyN'])
c = np.array([0.5]*self.numpoints)
t = [(255,0,0) for i in range(self.numpoints)]
data=np.column_stack((x,y,c))
x = data[:, 0]
c = data[:,2]
while True:
#print xy
#print cbys
if not pause:
for i in range(len(x)):
if sign[i]==1:
if x[i]<cbys[i]-0.1:
x[i]+=0.1
c[i]+=0.05
else:
x[i]=cbys[i]
elif sign[i]==-1:
if x[i]>cbys[i]+0.1:
x[i]-=0.1
c[i]-=0.05
else:
x[i]=cbys[i]
print c
#print data
#print c
yield data
def onClick(self,event):
global pause
pause ^=True
def update(self, i):
"""Update the scatter plot."""
data = next(self.stream)
print data[:,2]
# Set x and y data...
self.scat.set_offsets(data[:, :2])
# Set colors..
self.scat.set_array(data[:,2])
return self.scat,
def save(self):
plt.rcParams['animation.ffmpeg_path'] = 'C:\\ffmpeg\\bin\\ffmpeg.exe'
self.mywriter = animation.FFMpegWriter()
self.ani.save("myMovie.mp4",writer=self.mywriter)
self.show()
def show(self):
#mng = plt.get_current_fig_manager()
#mng.window.state('zoomed')
plt.show()
pause = False
if __name__ == '__main__':
a = AnimatedScatter(10)
a.show()
#a.save()
The problem you have is that the scatter plot is redrawn in every iteration, renormalizing the colors to the minimal and maximal value of c. So even at the start there will be a dot coresponding to the minmal and maximal color in the colormap already.
The solution would be to use a color normalization which is absolute from the start. The easiest way to do this is using the vmin and vmax keyword arguments.
ax.scatter(x, y, c=c, vmin=-1.5, vmax=2)
(This means that a value of c=-1.5 is the lowest color in the colormap and c=2 corresponds to the highest.)
Now it may be a bit hard to find the appropriate values, as the values are constantly changing in an infinite loop, so you need to find out appropriate values yourself depending on the use case.
I am coding a 2048 game via pygame. below is the relevant section of my code:
class Data():
def __init__(self):
self.data = getnull()
self.score = 0
def updatesprites(self): # EXP
spritelist = [[],[],[],[]]
for count in range(4): # for row loop
for i in range(4): # per column loop
if self.data[count][i] != 0:
spritelist[count]+= newSprite(str(self.data[count] [i])+".png") # error occurs here
spritelist[count][i].move(15 + i*115, 15 + count*115)
showSprite(spritelist[count][i])
class newSprite(pygame.sprite.Sprite):
def __init__(self,filename):
pygame.sprite.Sprite.__init__(self)
self.images=[]
self.images.append(loadImage(filename))
self.image = pygame.Surface.copy(self.images[0])
self.currentImage = 0
self.rect=self.image.get_rect()
self.rect.topleft=(0,0)
self.mask = pygame.mask.from_surface(self.image)
self.angle = 0
def addImage(self, filename):
self.images.append(loadImage(filename))
def move(self,xpos,ypos,centre=False):
if centre:
self.rect.center = [xpos,ypos]
else:
self.rect.topleft = [xpos,ypos]
----------------Main-------------------
from functions import *
from config import *
from pygame_functions import *
import pygame
screenSize(475,475) # call screen init
gameboard = newSprite("game board.png") # createboard
showSprite(gameboard)
game = Data()
game.updatesprites()
while True:
pass
when game.updatesprites() is called, "newSprite object is not iterable" error is raised in function Data.updatesprites
+ concatenates lists and strings, and adds numbers.
What you are trying to do, is to add an element to a list.
This is done as follows:
li.append(element) # adds the element to the end of the list
Or in your case:
spritelist[count].append(newSprite(str(self.data[count][i]) + ".png"))
Another solution: You could create a new type, that lets you add elements the way you were trying to:
class UglyList(list):
def __iadd__(self, other):
self.append(other)
You'd need to change another line here:
spritelist = [UglyList() for i in range(4)]
I'm trying to update data in a mayavi 3D plot. Some of the changes to the data don't affect the data shape so the mlab_source.set() method can be used (which updates underlying data and refreshes the display without resetting the camera, regenerating the VTK pipeline, regenerating the underlying data structure, etc. This is the best possible case for animation or quick plot updates.
If the underlying data changes shape, the documentation recommends using the mlab_source.reset() method, which while not recreating the entire pipeline or messing up the current scene's camera, does cause the data structure to be rebuilt, costing some performance overhead. This is causing crashes for me.
The worst way to go is completely deleting the plot source and generating a new one with a new call to mlab.mesh() or whatever function was used to plot the data. This recreates a new VTK pipeline, new data structure, and resets the scene's view (loses current zoom and camera settings, which can make smooth interactivity impossible depending on the application).
I've illustrated a simple example from my application in which a Sphere class can have it's properties manipulated (position, size, and resolution). While changing position and size cause the coordinates to refresh, the data remains the same size. However changing the resolution affects the number of latitude and longitude subdivisions used to represent the sphere, which changes the number of coordinates. When attempting to use the "reset" function, the interpreter crashes completely. I'm pretty sure this is a C level segfault in the VTK code based on similar errors around the web. This thread seems to indicate the core developers dealing with the problem almost 5 years ago, but I can't tell if it was truly solved.
I am on Mayavi 4.3.1 which I got along with the Enthought Tool Suite with Python(x, y). I'm on Windows 7 64-bit with Python 2.7.5. I'm using PySide, but I removed those calls and let mlab work by itself for this example.
Here's my example that shows mlab_source.set() working but crashes on mlab_source.reset(). Any thoughts on why it's crashing? Can others duplicate it? I'm pretty sure there are other ways to update the data through the source (TVTK?) object, but I can't find it in the docs and the dozens of traits related attributes are very difficult to wade through.
Any help is appreciated!
#Numpy Imports
from time import sleep
import numpy as np
from numpy import sin, cos, pi
class Sphere(object):
"""
Class for a sphere
"""
def __init__(self, c=None, r=None, n=None):
#Initial defaults
self._coordinates = None
self._c = np.array([0.0, 0.0, 0.0])
self._r = 1.0
self._n = 20
self._hash = []
self._required_inputs = [('c', list),
('r', float)]
#Assign Inputs
if c is not None:
self.c = c
else:
self.c = self._c
if r is not None:
self.r = r
else:
self.r = self._r
if n is not None:
self.n = n
else:
self.n = self._n
#property
def c(self):
"""
Center point of sphere
- Point is specified as a cartesian coordinate triplet, [x, y, z]
- Coordinates are stored as a numpy array
- Coordinates input as a list will be coerced to a numpy array
"""
return self._c
#c.setter
def c(self, val):
if isinstance(val, list):
val = np.array(val)
self._c = val
#property
def r(self):
"""
Radius of sphere
"""
return self._r
#r.setter
def r(self, val):
if val < 0:
raise ValueError("Sphere radius input must be positive")
self._r = val
#property
def n(self):
"""
Resolution of curvature
- Number of points used to represent circles and arcs
- For a sphere, n is the number of subdivisions per hemisphere (in both latitude and longitude)
"""
return self._n
#n.setter
def n(self, val):
if val < 0:
raise ValueError("Sphere n-value for specifying arc/circle resolution must be positive")
self._n = val
#property
def coordinates(self):
"""
Returns x, y, z coordinate arrays to visualize the shape in 3D
"""
self._lazy_update()
return self._coordinates
def _lazy_update(self):
"""
Only update the coordinates data if necessary
"""
#Get a newly calculated hash based on the sphere's inputs
new_hash = self._get_hash()
#Get the old hash
old_hash = self._hash
#Check if the sphere's state has changed
if new_hash != old_hash:
#Something changed - update the coordinates
self._update_coordinates()
def _get_hash(self):
"""
Get the sphere's inputs as an immutable data structure
"""
return tuple(map(tuple, [self._c, [self._r, self._n]]))
def _update_coordinates(self):
"""
Calculate 3D coordinates to represent the sphere
"""
c, r, n = self._c, self._r, self._n
#Get the angular distance between latitude and longitude lines
dphi, dtheta = pi / n, pi / n
#Generate a latitude and longitude grid
[phi, theta] = np.mgrid[0:pi + dphi*1.0:dphi,
0:2 * pi + dtheta*1.0:dtheta]
#Map the latitude longitude grid into cartesian x, y, z coordinates
x = c[0] + r * cos(phi) * sin(theta)
y = c[1] + r * sin(phi) * sin(theta)
z = c[2] + r * cos(theta)
#Store the coordinates
self._coordinates = x, y, z
#Update the hash to coordinates to these coordinates
self._hash = self._get_hash()
if __name__ == '__main__':
from mayavi import mlab
#Make a sphere
sphere = Sphere()
#Plot the sphere
source = mlab.mesh(*sphere.coordinates, representation='wireframe')
#Get the mlab_source
ms = source.mlab_source
#Increase the sphere's radius by 2
sphere.r *= 2
#New coordinates (with larger radius)
x, y, z = sphere.coordinates
#Currently plotted coordinates
x_old, y_old, z_old = ms.x, ms.y, ms.z
#Verify that new x, y, z are all same shape as old x, y, z
data_is_same_shape = all([i.shape == j.shape for i, j in zip([x_old, y_old, z_old], [x, y, z])])
#Pause to see the old sphere
sleep(2)
#Check if data has changed shape... (shouldn't have)
if data_is_same_shape:
print "Updating same-shaped data"
ms.set(x=x, y=y, z=z)
else:
print "Updating with different shaped data"
ms.reset(x=x, y=y, z=z)
#Increase the arc resolution
sphere.n = 50
#New coordinates (with more points)
x, y, z = sphere.coordinates
#Currently plotted coordinates
x_old, y_old, z_old = ms.x, ms.y, ms.z
#Verify that new x, y, z are all same shape as old x, y, z
data_is_same_shape = all([i.shape == j.shape for i, j in zip([x_old, y_old, z_old], [x, y, z])])
#Pause to see the bigger sphere
sleep(2)
#Check if data has changed shape... (should have this time...)
if data_is_same_shape:
print "Updating same-shaped data"
ms.set(x=x, y=y, z=z)
else:
#This is where the segfault / crash occurs
print "Updating with different shaped data"
ms.reset(x=x, y=y, z=z)
mlab.show()
EDIT:
I just verified that all of these mlab_source tests pass for me which includes testing reset on an MGridSource. This does show some possible workarounds like accessing source.mlab_source.dataset.points ... maybe there's a way to update the data manually?
EDIT 2:
I tried this:
p = np.array([x.flatten(), y.flatten(), z.flatten()]).T
ms.dataset.points = p
ms.dataset.point_data.scalars = np.zeros(x.shape)
ms.dataset.points.modified()
#Regenerate the data structure
ms.reset(x=x, y=y, z=z)
It appears that modifying the TVTK Polydata object directly partly works. It appears that it's updating the points without also auto-fixing the connectivity, which is why I have to also run the mlab_source.reset(). I assume the reset() can work now because the data coming in has the same number of points and the mlab_source handles auto-generating the connectivity data. It still crashes when reducing the number of points, maybe because connectivity data exists for points that don't exist? I'm still very frustrated with this.
EDIT 3:
I've implemented the brute force method of just generating a new surface from mlab.mesh(). To prevent resetting the view I disable rendering and store the camera settings, then restore the camera settings after mlab.mesh() and then re-enable rendering. Seems to work quick enough - still wish underlying data could be updated with reset()
Here's the entire class I use to manage plotting objects (responds to GUI signals after an edit has been made).
class PlottablePrimitive(QtCore.QObject):
def __init__(self, parent=None, shape=None, scene=None, mlab=None):
super(PlottablePrimitive, self).__init__(parent=parent)
self._shape = None
self._scene = None
self._mlab = None
self._source = None
self._color = [0.706, 0.510, 0.196]
self._visible = True
self._opacity = 1.0
self._camera = {'position': None,
'focal_point': None,
'view_angle': None,
'view_up': None,
'clipping_range': None}
if shape is not None:
self._shape = shape
if scene is not None:
self._scene = scene
if mlab is not None:
self._mlab = mlab
#property
def shape(self):
return self._shape
#shape.setter
def shape(self, val):
self._shape = val
#property
def color(self):
return self._color
#color.setter
def color(self, color):
self._color = color
if self._source is not None:
surface = self._source.children[0].children[0].children[0]
surface.actor.mapper.scalar_visibility = False
surface.actor.property.color = tuple(color)
def plot(self):
x, y, z = self._shape.coordinates
self._source = self._mlab.mesh(x, y, z)
def update_plot(self):
ms = self._source.mlab_source
x, y, z = self._shape.coordinates
a, b, c = ms.x, ms.y, ms.z
data_is_same_shape = all([i.shape == j.shape for i, j in zip([a, b, c], [x, y, z])])
if data_is_same_shape:
print "Same Data Shape... updating"
#Update the data in-place
ms.set(x=x, y=y, z=z)
else:
print "New Data Shape... resetting data"
method = 'new_source'
if method == 'tvtk':
#Modify TVTK directly
p = np.array([x.flatten(), y.flatten(), z.flatten()]).T
ms.dataset.points = p
ms.dataset.point_data.scalars = np.zeros(x.shape)
ms.dataset.points.modified()
#Regenerate the data structure
ms.reset(x=x, y=y, z=z)
elif method == 'reset':
#Regenerate the data structure
ms.reset(x=x, y=y, z=z)
elif method == 'new_source':
scene = self._scene
#Save camera settings
self._save_camera()
#Disable rendering
self._scene.disable_render = True
#Delete old plot
self.delete_plot()
#Generate new mesh
self._source = self._mlab.mesh(x, y, z)
#Reset camera
self._restore_camera()
self._scene.disable_render = False
def _save_camera(self):
scene = self._scene
#Save camera settings
for setting in self._camera.keys():
self._camera[setting] = getattr(scene.camera, setting)
def _restore_camera(self):
scene = self._scene
#Save camera settings
for setting in self._camera.keys():
if self._camera[setting] is not None:
setattr(scene.camera, setting, self._camera[setting])
def delete_plot(self):
#Remove
if self._source is not None:
self._source.remove()
self._source = None