I created a class that has different functions that output different graphs. One of the function is to calculate the bid width for whatever variable is being passed. Last night my notebook was running wonderfully but now I'm getting NameError: name 'bin_width' is not defined and I'm not sure why. I tested the bin function in a separate notebook and it works but for some reason it's not working in the class.
Error:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-47-1bce9e9c118e> in <module>
2 histo = Graphs('YRONJOB', None, None, None)
3 #Call histogram() function to apply to object
----> 4 histo.histogram()
<ipython-input-46-02e598bef21f> in histogram(self)
42
43 #Create variable that we call the function to calculate the bin width
---> 44 bin = bin_width(self.A)
45 print(bin)
46
NameError: name 'bin_width' is not defined
Can someone please let me know what I'm doing wrong and how to fix the issue. Below I attached my import cell, the first four functions of my class, and the cell where I created the object.
#Import library
import pandas as pd
import math
import numpy as np
import matplotlib.pyplot as plt
#Automatically creates a dataframe don't need pd.DataFrame
data = pd.read_csv("/Users/tianachargin/Desktop/PythonSG/STAT 4490/WidgeOne_CSV.csv")
#print out dataset
print(data)
class Graphs:
#Constructor with parameters
#Self isn't a pass by value parameter but it allows you to reference
def __init__(self, quantVar1, quantVar2, qualVar1, qualVar2):
self.A = quantVar1 #First quantitative variable
self.B = quantVar2 #Second quantitative variable
self.C = qualVar1 #First qualitative variable
self.D = qualVar2 #Second qualitative variable
#Function that calculates bin width for the histogram
def bin_width(variable):
#Import libaray
import math
#Create variable to create array for bins
#Find min of column
min = data[variable].min()
#Find max of column
max = data[variable].max()
#Find the the count of rows (number of data/size/n)
index = data.index
number_of_rows = len(index)
#Calculate number of bins and round up
num_of_bins = (math.ceil(math.sqrt(number_of_rows)))
#Calculate bin width (max - min)/# of bins
bin_width = ((max - min)/num_of_bins)
#Round bin width to one decimal place
increment_bin = round(bin_width, 1)
#Start bin
start_bin = (min - increment_bin)
#End bin
end_bin = (max + increment_bin)
return start_bin, end_bin, increment_bin
#Histogram Function
def histogram(self):
#Import libraries
import math
import numpy as np
import matplotlib.pyplot as plt
#Create variable that we call the function to calculate the bin width
bin = bin_width(self.A)
#Start at value = bin[0], Stop at value = bin[1], Increment by value of bin[2]
bins = np.array(np.arange(start = bin[0], stop = bin[1], step = bin[2]))
#Histogram function
plt.hist(data[self.A], bins, label = self.A, color = "red")
#x-axis label
plt.xlabel(self.A, fontsize = 16)
#y-axis lable
plt.ylabel("Frequency of " + self.A, fontsize = 16)
#Title of graph
plt.title("Histogram of " + self.A, loc = 'center')
plt.show()
return
#Stacked Histogram Function
def stacked_histogram(self):
#Import libraries
import numpy as np
from matplotlib import pyplot as plt
#Create combonations of the values for the two options
data[self.C + "-" + self.D] = data[self.C] + " " + data[self.D]
combos = np.unique(data[self.C + "-" + self.D])
#Create variable that we call the function to calculate the bin width
bin = bin_width(self.A)
#Start at value = bin[0], Stop at value = bin[1], Increment by value of bin[2]
bins = np.array(np.arange(start = bin[0], stop = bin[1], step = bin[2]))
#Create histogram
for i in range(len(combos)):
plt.hist(data[data[self.C + "-" + self.D].isin(combos[i:(len(combos))])][self.A], bins, label = combos[i:(len(combos))])
#x-axis label
plt.xlabel(self.A, fontsize = 16)
#y-axis lable
plt.ylabel("Frequency of ", fontsize = 16)
#Legend of graph
plt.legend(loc = 'upper left')
#Title of graph
plt.title("Histogram of " + self.A + " with unique combinations of " + self.D + " and " + self.C, loc = 'center')
plt.show()
return
#Overlapping Histogram Function
def overlap_histogram(self):
#Import libraries
import numpy as np
from matplotlib import pyplot as plt
#Create variable that we call the function to calculate the bin width
bin = bin_width(self.A)
#Start at value = bin[0], Stop at value = bin[1], Increment by value of bin[2]
bins = np.array(np.arange(start = bin[0], stop = bin[1], step = bin[2]))
#Create histogram
plt.hist(data[self.A], bins, alpha = 0.5, label = self.A, color = "red")
plt.hist(data[self.B], bins, alpha = 0.5, label = self.B, color = "blue")
#x-axis label
plt.xlabel("Variables", fontsize = 16)
#y-axis lable
plt.ylabel("Frequency", fontsize = 16)
#Legend of graph
plt.legend(loc = 'upper left')
#Title of graph
plt.title("Overlapping Histogram of Variables " + self.A + " and " + self.B, loc = 'center')
plt.show()
#Create an object from class Graphs that will have one parameter
histo = Graphs('YRONJOB', None, None, None)
#Call histogram() function to apply to object
histo.histogram()
first thing i want to say is that youre not supposed to import modules in functions. its enough to import them on the top.
Second thing, youre doing
def bin_width(variable)
and using like this
bin_width(self.A)
right way
def bin_width(self, variable)
usage:
bin = bin_width(self, yourvariable)
Related
I would like help to plot a counterf only within the region bounded by the blue area in the image, not in the whole graph. I am trying to use matplotlib mpath and mpatches but I am getting several errors.
How could I plot the difference in levels (contorf) only within the area delimited by the blue markings?
Here is my code and the picture
#import base modules
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.interpolate import LinearNDInterpolator
from matplotlib.collections import PatchCollection
import matplotlib.path as mpath
import matplotlib.patches as mpatches
from mpl_toolkits.axes_grid1 import make_axes_locatable
#Loading the images
img1953 = plt.imread('O1953_9960_A3_1m.tif')
img1999 = plt.imread('O1999_9523_A3_1m.tif')
img2004 = plt.imread('O2004_2385c_A3_1m.tif')
#extract data from surfer files with pandas and name the columns as x and y, first line omited
area = pd.read_csv('diff_analyse_grd.bln', names=['x1', 'y1'], skiprows=1)
slope = pd.read_csv("Abbruchkante.bln", names=['x2', 'y2'], skiprows=1)
crack = pd.read_csv("Anrisskante.bln", names=['x3', 'y3'], skiprows=1)
xmin, xmax = -1100, -200 #set the maximum and miniumum values for the axIs:
ymin, ymax = 1500, 2100
#Read csv from grid/countour file, 1999
grid = np.loadtxt('kr_99_A3_o25.dat', delimiter = ' ', skiprows = 1, usecols = [1,2,3])
x99 = grid[:,0]
y99 = grid[:,1]
z99 = grid[:,2]
#linear space with 600x900 values between min and max graphic values
xi = np.linspace(xmin, xmax, 900)
yi = np.linspace(ymin, ymax, 600)
X, Y = np.meshgrid(xi, yi)
#Using LinearNDInterpolation, year 1999
interpolation99 = LinearNDInterpolator(list(zip(x99, y99)), z99)#https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.LinearNDInterpolator.html
zi99 = interpolation99(X, Y)
#Read csv from grid/countour file, year 1953
grid = np.loadtxt('kr_53_A3_o25.dat', delimiter = ' ', skiprows = 1, usecols = [1,2,3])
x53 = grid[:,0]
y53 = grid[:,1]
z53 = grid[:,2]
#Using LinearNDInterpolation, year 1953
interpolation53 = LinearNDInterpolator(list(zip(x53,y53)), z53)
zi53 = interpolation53(X,Y)
#Calculation of the hight variation:
dh5399 = zi53 - zi99
#Plot graph 1953 - 1999
plt.title('Hangrutschung im Blaubachgraben \n \n Differenz der Geländeoberflachen \n 1953 - 1999')
plt.imshow(img1953,cmap='gray', extent=(xmin, xmax, ymin, ymax))
plt.plot(area.x1,area.y1,'b-', label ='Studienbereich', linewidth = 2)
plt.plot(slope.x2,slope.y2,'r-', label = 'Abbruchkante')
plt.plot(crack.x3,crack.y3,'r--', label = 'Anrisskante')
cs = plt.contour(X,Y,zi99,levels=10, colors='#333')
plt.clabel(cs,inline=True, colors = 'k')
plt.legend(loc='upper right')
plt.xlabel('North [m]')
plt.ylabel('East [m]')
plt.xlim(xmin,xmax)
plt.ylim(ymin,ymax)
cs = plt.contourf(X, Y, dh5399, cmap='rainbow', vmin=-5, vmax=17)
#Setting colorbar right the axis
ax = plt.gca()
divider = make_axes_locatable(ax)
cax = divider.append_axes('right',size='3%',pad=0.1)
cbar = plt.colorbar(cs, cax=cax)
cbar.set_label('\u0394H [m]', rotation = 360, loc = 'top')
plt.tight_layout()
plt.savefig('Dif1.png',dpi=400)
plt.show()
My code is a fair bit more advanced, but in simple terms I am looking to place and rotate an image of a plane along a path using matplotlib. Ideally I would be able to select the angle and how far along the path the image should be placed. Any ideas? My ideal output would be something like this (ignoring the coordinates I already fixed that in my real code).
Image of Norway used:
Code
import matplotlib.pyplot as plt
import matplotlib.image as img
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def x2map(x, x_scale):
return x * x_scale
def y2map(y, y_scale):
return (1 - y) * y_scale
if __name__ == "__main__":
image_url = "Norge2.png"
# Obtains the scaling for the figure
map = img.imread(image_url)
fig, ax = plt.subplots()
im = ax.imshow(map)
_, x_scale = plt.xlim()
y_scale, _ = plt.ylim()
# Fixes the axis to 0-1 and 0-1
positions_x = [i * x_scale / 10 for i in range(0, 11)]
positions_y = [i * y_scale / 10 for i in range(0, 11)]
labels = [i / 10 for i in range(0, 11)]
ax.set_xticks(positions_x)
ax.set_xticklabels([i / 10 for i in range(0, 11)])
ax.set_yticks(positions_y)
ax.set_yticklabels([(10 - i) / 10 for i in range(0, 11)])
route_color = "red"
route_ls = "-"
city_marker ="o"
city_color = "red"
A = [x2map(0.125,x_scale), y2map(0.14,y_scale)]
B = [x2map(0.772,x_scale), y2map(0.92,y_scale)]
plt.plot(
[A[0], B[0]], [A[1], B[1]], marker='o', color=route_color, ls=route_ls
)
plt.show()
I want to create an interactive scatter plot so the user can select points with the cursor, so the chosen points are highlighted and the rest are faded.
Right now it only works if the color is changed, how can i change the opacity and keep the original colors?
import numpy as np
from numpy.random import rand
from matplotlib.widgets import LassoSelector
from matplotlib.path import Path
import matplotlib.pyplot as plt
class SelectFromCollection(object):
def __init__(self, ax, collection,c, alpha_other=0.3):
self.canvas = ax.figure.canvas
self.collection = collection
self.alpha_other = alpha_other
self.xys = collection.get_offsets()
self.Npts = len(self.xys)
self.c = c
# Ensure that we have separate colors for each object
self.fc = collection.get_facecolors()
if len(self.fc) == 0:
raise ValueError('Collection must have a facecolor')
elif len(self.fc) == 1:
self.fc = np.tile(self.fc, (self.Npts, 1))
self.lasso = LassoSelector(ax, onselect=self.onselect)
self.ind = []
def onselect(self, verts):
path = Path(verts)
self.ind = np.nonzero(path.contains_points(self.xys))[0]
self.fc[:, -1] = self.alpha_other
self.fc[self.ind, -1] = 1
self.collection.set_facecolors(self.fc)
self.canvas.draw_idle()
def disconnect(self):
self.lasso.disconnect_events()
self.fc[:, -1] = 1
self.collection.set_facecolors(self.fc)
self.canvas.draw_idle()
np.random.seed(1)
x, y, c = rand(3, 100)
subplot_kw = dict(xlim=(0, 1), ylim=(0, 1), autoscale_on=False)
fig, ax = plt.subplots(subplot_kw=subplot_kw)
pts = ax.scatter(x, y,c=c, s=100)
selector = SelectFromCollection(ax, pts, c)
plt.show()
Solved, I used the method self.collection.get_facecolors(), to get the format and values, then I just changed the value of the 3rd column for the chosen indices like this:
fc = self.collection.get_facecolors()
fc[self.ind, 3] = 1
fc[others, 3] = self.alpha_other
self.collection.set_facecolors(fc)
cheers
I wrote a program to plot oscilloscope data and make a KDE scatter plot with a colorbar. Unfortunately it requires a third party lib (readTrc) as well as the oscilloscope binary file which size is 200MB. The lib can be found on github.
import pandas as pd
import readTrc
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import collections
from scipy.stats import gaussian_kde
trcpath = 'filename.trc' #Binary Oscilloscope File (200 MB)
datX, datY, m = readTrc.readTrc(trcpath)
srx, sry = pd.Series(datX * 1000), pd.Series(datY * 1000)
df = pd.concat([srx, sry], axis = 1)
df.set_index(0, inplace = True)
df = df.abs() #Build Dataframe from above file
fig = plt.figure()
#Eliminate Noise
df[df < 3] = None
df = df.dropna()
#x and y axes data to plot
q1 = np.array(df[1].tolist()[:-2])
q2 = np.array(df[1].tolist()[1:-1])
q3 = np.array(df[1].tolist()[2:])
dq1 = q2 - q1
dq2 = q3 - q2
#Create first Dataset
qqstack = []
xy = np.vstack([dq1,dq2])
#Determine max value for colorbar (highest repeating x/y combination)
df_d = pd.DataFrame([dq1,dq2]).T
for idx, row in df_d.iterrows():
if row[0] == row[1]:
qqstack.append((row[0], row[1]))
cbar_max = collections.Counter(qqstack).most_common(1)[0][-1]
#sort to show most present values last
z = gaussian_kde(xy)(xy)
idx = z.argsort()
x, y, z = dq1[idx], dq2[idx], z[idx]
#plot graph
plt.scatter(x, y,
c=z,
s=20,
cmap = plt.cm.get_cmap('jet'))
#create colormap variable
sm = plt.cm.ScalarMappable(cmap = plt.cm.get_cmap('jet'),
norm = matplotlib.colors.PowerNorm(vmin = -0.1, vmax = cbar_max, gamma = 1))
sm._A = []
fig.colorbar(sm, ticks = range(0, cbar_max, 250))
plt.grid(zorder = 0, alpha = 0.3)
plt.xlabel('dq1 / mV')
plt.ylabel('dq2 / mV')
plt.show()
How can I adjust the color allocation in the plot? I want there to be less blue space so the transition is visible more, like on this graph:
My slider won't change the value of the parameter I give it. The slider moves, but the value doesn't change. Of import here is 'temperature' which I need to vary with slider 2.
Also, winsound won't play anything and my sliders aren't labeled. What the heck is going on here?
import winsound
import pygame
import time
from visual.controls import *
from visual.graph import *
from math import *
temperature = 50
funct1 = gcurve(color=(temperature*0.04, (temperature*0.04)-2, (temperature*0.04)-2))
for x in arange (0., 100.1, 0.1):
funct1.plot(pos=(x,5.*cos(2.*x)))
def setdir(direction):
cube.dir = direction
def setrate(obj): # called on slider drag events
cuberate(obj.value) # value is min-max slider position
def cuberate(value):
cube.dtheta = 2*value*pi/1e3
def woosh(sound):
winsound.playsound('%s.wav' % sound, winsound.sphere.wav)
x=0
y=0
z=0
w = 350
display(x=w, y=0, width=w, height=w, range=1.5, forward=-vector(0,0,1), newzoom=1)
c = controls(x=0, y=0, width=w, height=w, range=60)
ctrl = slider(pos=(-50,20), width=7, length=100, axis=(1,0,0), text='Temperature', min=0., max=100., value=temperature)
s1 = slider(pos=(-50,40), width=7, length=100, axis=(1,0,0), text='Angular Velocity', action=lambda: setrate(s1))
cube = sphere(color=(temperature*0.04, (temperature*0.04)-2, (temperature*0.04)-2), material=materials.rough, pos=(x,y,z))
sphere.velocity = vector(x,y,z)
setrate(s1)
setdir(-1)
side = .4
thk = 0.3
t=0
dt=0.1
while True:
rate(100)
cube.p = vector (sin(t*0.02*temperature),sin(t*0.03*temperature),sin(t*0.04*temperature))
cube.rotate(axis=(0,1,0), angle=cube.dir*cube.dtheta)
t = t + dt
cube.pos = cube.p*sin(t*temperature/100)/5
woosh
if not (side > cube.x > -side):
cube.p.x = -cube.p.x
if not (side > cube.y > -side):
cube.p.y = -cube.p.y
if not (side > cube.z > -side):
cube.p.z = -cube.p.z
I think it was an oversight of the letter "s" in the word value. Replace value with values in line ctrl:
ctrl = slider(pos=(-50,20), width=7, length=100, axis=(1,0,0), text='temperature', min=0, max=50, values = temperature)