matplotlib.pyplot errorbar ValueError depends on array length? - arrays

Good afternoon.
I've been struggling with this for a while now, and although I can find similiar problems online, nothing I found could really help me resolve it.
Starting with a standard data file (.csv or .txt, I tried both) containing three columns (x, y and the error of y), I want to read in the data and generate a line plot including error bars.
I can plot the x and y values without a problem, but if I want to add errorbars using the matplotlib.pyplot errorbar utility, I get the following error message:
ValueError: yerr must be a scalar, the same dimensions as y, or 2xN.
The code below works if I use some arbitrary arrays (numpy or plain python), but not for data read from the file. I've tried converting the tuples which I obtain from my input code to numpy arrays using asarray, but to no avail.
import numpy as np
import matplotlib.pyplot as plt
row = []
with open("data.csv") as data:
for line in data:
row.append(line.split(','))
column = zip(*row)
x = column[0]
y = column[1]
yer = column[2]
plt.figure()
plt.errorbar(x,y,yerr = yer)
fig = plt.gcf()
fig.set_size_inches(18.5, 10.5)
fig.savefig('example.png', dpi=300)
It must be that I am overlooking something. I would be very grateful for any thoughts on the matter.

yerr should be the added/subtracted error from the y value. In your case the added equals the subtracted equals half of the third column.
import numpy as np
import matplotlib.pyplot as plt
data = np.loadtxt('data.csv', delimiter=',')
plt.figure()
yerr_ = np.tile(data[:, 2]/2, (2, 1))
plt.errorbar(data[:, 0], data[:, 1], yerr=yerr_)
plt.xlim([-1, 3])
plt.show()
data.csv
0,2,0.3
1,4,0.4
2,3,0.15

Related

Updating matplotlib figures within a for loop in python

I am trying to move a magnetic object and update its magnetic field which is then plotted in a for loop. I want to update the matplotlib figures such that the last figure is deleted before the latest one is shown (with delay as can be seen). I want this to happen in one window (I might be using the wrong technical term) only. Currently it creates a new figure every time it updates the magnetic field. I tried using plt.cla(), plt.close(), and plt.clf() without success. The code is given below. Any help will be much appreciated
import matplotlib.pyplot as plt
import numpy as np
from magpylib.source.magnet import Box,Cylinder
from magpylib import Collection, displaySystem
# create magnets
s1 = Box(mag=(0,0,600), dim=(3,3,3), pos=(-4,0,20))
# calculate the grid
xs = np.linspace(-15,10,33)
zs = np.linspace(-5,25,44)
POS = np.array([(x,0,z) for z in zs for x in xs])
X,Z = np.meshgrid(xs,zs)
for i in range(20):
Bs = s1.getB(POS).reshape(44,33,3) #B-field
s1.move((0,0,-1))
# create figure
fig = plt.figure(figsize=(5,9))
# display field in xz-plane using matplotlib
U,V = Bs[:,:,0], Bs[:,:,2]
plt.streamplot(X, Z, U, V, color=np.log(U**2+V**2))
plt.show()
sleep(0.2)```
You want to make use of matplotlib's interactive mode by invoking plt.ion() and clear the axes after every frame in the loop using plt.cla():
import matplotlib.pyplot as plt
import numpy as np
from magpylib.source.magnet import Box,Cylinder
from magpylib import Collection, displaySystem
fig, ax = plt.subplots()
# create magnets
s1 = Box(mag=(0,0,600), dim=(3,3,3), pos=(-4,0,20))
# calculate the grid
xs = np.linspace(-15,10,33)
zs = np.linspace(-5,25,44)
POS = np.array([(x,0,z) for z in zs for x in xs])
X,Z = np.meshgrid(xs,zs)
plt.ion()
plt.show()
img=0
for i in range(20):
Bs = s1.getB(POS).reshape(44,33,3) #B-field
s1.move((0,0,-1))
U,V = Bs[:,:,0], Bs[:,:,2]
ax.streamplot(X, Z, U, V, color=np.log(U**2+V**2))
plt.gcf().canvas.draw()
plt.savefig('{}'.format(img))
plt.pause(0.01)
plt.clf()
img=img+1

How to create pandas dataframe from array([[[135, 2270.24]]], dtype=object)

I am embarassed with this. I would like to transform this array to pandas dataframe with one column let's say called "feature" and one value: [135, 2270.24]:
array([[[135, 2270.24]]], dtype=object)
I tried this but returns ValueError: Must pass 2-d input
df = pd.DataFrame(C, columns = ['feature']) with C the array.
I'm not entirely sure I follow exactly what you're asking for. But if my interpretation is correct you're looking for something like this?
import pandas as pd
import numpy as np
# setup
val = np.array([[[135, 2270.24]]])
# logic
data = [{'feature': val[0][0]}]
df = pd.DataFrame(data)
Output df:
feature
0 [135.0, 2270.24]

Printing numpy array and dataframe list, any dependencies?

I am trying to print two different lists with numpy and pandas respectively.
The strange thing is that I can only print one list at a time by commenting the other one with all its accosiated code. Do mumpy and pandas have any dependcies?
import numpy as np
import pandas as pd
np.array = []
for i in range(7):
np.array.append([])
np.array[i] = i
values = np.array
print(np.power(np.array,3))
df = pd.DataFrame({'X':[78,85,96,80,86], 'Y':[84,94,89,83,86],'Z':[86,97,96,72,83]})
print(df)
I'm not sure what you mean by "I can only print one list at a time by commenting the other one with all its accosiated code", but any strange behavior you're seeing probably comes from you assigning to np.array. You should name your variable something different, e. g. array. Perhaps you were trying to do this:
arr = []
for i in range(7):
arr.append([])
arr[i] = i
values = np.array(arr)

Create A Scatterplot from Pandas DataFrame

I'm working on a Pandas DF question and I am having trouble converting some Pandas data into a usable format to create a Scatter Plot.
Here is the code below, please let me know what I am doing wrong and how I can correct it going forward. Honest criticism is needed as I am a beginner.
# Import Data
df = pd.read_csv(filepath + 'BaltimoreData.csv')
df = df.dropna()
print(df.head(20))
# These are two categories within the data
df.plot(df['Bachelors degree'], df['Median Income'])
# Plotting the Data
df.plot(kind = 'scatter', x = 'Bachelor degree', y = 'Median Income')
df.plot(kind = 'density')
Simply plot x on y as below, where df is your dataframe and x and y are your dependent and independent variables:
import matplotlib.pyplot as plt
import pandas
plt.scatter(x=df['Bachelors degree'], y=df['Median Income'])
plt.show()
You can use scatter plot from pandas.
import pandas
import matplotlib.pyplot as plt
plt.style.use('ggplot')
df.plot.scatter(x='Bachelors degree', y='Median Income');
plt.show()

IndexError: list assignment index out of range in python 2.7.11

I was just solving a problem using python, and my codes are:
from math import sin,pi
import numpy
import numpy as np
import pylab
N=20
x = np.linspace(0,1, N)
def v(x):
return 100*sin(pi*x)
#set up initial condition
u0 = [0.0] # Boundary conditions at t= 0
for i in range(1,N):
u0[i] = v(x[i])
And I would want to plot the results by updating v(x) in range(0, N) after. it looks simple but perhaps you guys could help since it gives me an error, like
Traceback (most recent call last):
File "/home/universe/Desktop/Python/sample.py", line 13, in <module>
u0[i] = v(x[i])
IndexError: list assignment index out of range
You could change u0[i] = v(x[i]) to u0.append(v(x[i])). But you should write more elegantly as
u0 = [v(xi) for xi in x]
Indices i are bug magnets.
Since you are using numpy, I'd suggest using np.vectorize. That way you can pass the array x directly to the function and the function will return an array of the same size with the function applied on each element of the input array.
from math import sin,pi
import numpy
import numpy as np
import pylab
N=20
x = np.linspace(0,1, N)
def v(x):
return 100*sin(pi*x)
vectorized_v = np.vectorize(v) #so that the function takes an array of x's and returns an array again
u0 = vectorized_v(x)
Out:
array([ 0.00000000e+00, 1.64594590e+01, 3.24699469e+01,
4.75947393e+01, 6.14212713e+01, 7.35723911e+01,
8.37166478e+01, 9.15773327e+01, 9.69400266e+01,
9.96584493e+01, 9.96584493e+01, 9.69400266e+01,
9.15773327e+01, 8.37166478e+01, 7.35723911e+01,
6.14212713e+01, 4.75947393e+01, 3.24699469e+01,
1.64594590e+01, 1.22464680e-14])
u is a list with one element, so you can't assign values to indices that don't exist. Instead make u a dictionary
u = {}
u[0] = 0.0
for i in range(1,N):
u[i] = v(x[i])

Resources