ValueError: Points must be Nx2 array, got 2x5 - python

I'm trying to make an animation and am looking at the code of another stack overflow question. The code is the following
import matplotlib.pyplot as plt
from matplotlib import animation as animation
import numpy as np
import pandas as pd
import io
u = u"""Time M1 M2 M3 M4 M5
1 1 2 3 1 2
2 1 3 3 1 2
3 1 3 2 1 3
4 2 2 3 1 2
5 3 3 3 1 3
6 2 3 4 1 4
7 2 3 4 3 3
8 3 4 4 3 4
9 4 4 5 3 3
10 4 4 5 5 4"""
df_Bubble = pd.read_csv(io.StringIO(u), delim_whitespace=True)
time_count = len(df_Bubble)
colors = np.arange(1, 6)
x = np.arange(1, 6)
max_radius = 25
fig, ax = plt.subplots()
pic = ax.scatter(x, df_Bubble.iloc[0, 1:], s=100, c=colors)
pic.set_offsets([[np.nan]*len(colors)]*2)
ax.axis([0,7,0,7])
def init():
pic.set_offsets([[np.nan]*len(colors)]*2)
return pic,
def updateData(i):
y = df_Bubble.iloc[i, 1:]
area = np.pi * (max_radius * y / 10.0) ** 2
pic.set_offsets([x, y.values])
pic._sizes = area
i+=1
return pic,
ani = animation.FuncAnimation(fig, updateData,
frames=10, interval = 50, blit=True, init_func=init)
plt.show()
When I run this code unchanged I get the error
ValueError: Points must be Nx2 array, got 2x5
I have looked at similar threads on this question and have come to the conclusion that the problem has to do with the line with [[np.nan]*len(colors)]*2. Based on the examples I found, I thought that changing a part of this line to an array might help, but none of my attempts have worked, and now I'm stuck. I would be grateful for any help.

set_offsets expects a Nx2 ndarray and you provide 2 arrays with 5 elements each in updateData(i) and 2 lists with 5 elements each in init()
def init():
pic.set_offsets(np.empty((len(colors),2)))
return pic,
def updateData(i):
y = df_Bubble.iloc[i, 1:]
area = np.pi * (max_radius * y / 10.0) ** 2
#pic.set_offsets(np.hstack([x[:i,np.newaxis], y.values[:i, np.newaxis]]))
pic.set_offsets(np.transpose((x, y.values)))
pic._sizes = area
i+=1
return pic,

Related

plot line between points pandas

I would like to plot lines between two points and my points are defined in different columns.
#coordinates of the points
#point1(A[0],B[0])
#point2(C[0],D[0])
#line between point1 and point 2
#next line would be
#point3(A[1],B[1])
#point4(C[1],D[1])
#line between point3 and point 4
plot_result:
A B C D E F
0 0 4 7 1 5 1
1 2 5 8 3 3 1
2 3 4 9 5 6 1
3 4 5 4 7 9 4
4 6 5 2 1 2 7
5 1 4 3 0 4 7
i tried with this code:
import numpy as np
import matplotlib.pyplot as plt
for i in range(0, len(plot_result.A), 1):
plt.plot(plot_result.A[i]:plot_result.B[i], plot_result.C[i]:plot_result.D[i], 'ro-')
plt.show()
but it is a invalid syntax. I have no idea how to implement this
The first two parameters of the method plot are x and y which can be single points or array-like objects. If you want to plot a line from the point (x1,y1) to the point (x2,y2) you have to do something like this:
for plot_result in plot_result.values: # if plot_results is a DataFrame
x1 = row[0] # A[i]
y1 = row[1] # B[i]
x2 = row[2] # C[i]
y2 = row[3] # D[i]
plt.plot([x1,x2],[y1,y2]) # plot one line for every row in the DataFrame.

grouping boxplots matplotlib

Is there a way to group boxplots in matplotlib WITHOUT the use of seaborn or some other library?
e.g. in the following, I want to have blocks along the x axis, and plot values grouped by condition (so there will be 16 boxes). Like what seaborn's hue argument accomplishes.
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
blocks = 4
conditions = 4
ndatapoints = blocks * conditions
blockcol = np.repeat(list(range(1, conditions+1)), blocks)
concol = np.repeat(np.arange(1, conditions+1, 1), blocks)
trialcol = np.arange(1, ndatapoints+1, 1)
valcol = np.random.normal(0, 1, ndatapoints)
raw_data = {'blocks': np.repeat(list(range(1, conditions+1)), blocks),
'condition': list(range(1, conditions+1))*blocks,
'trial': np.arange(1, ndatapoints+1, 1),
'value': np.random.normal(0, 1, ndatapoints)}
df = pd.DataFrame(raw_data)
df
blocks condition trial value
0 1 1 1 1.306146
1 1 2 2 -0.024201
2 1 3 3 -0.374561
3 1 4 4 -0.093366
4 2 1 5 -0.548427
5 2 2 6 -1.205077
6 2 3 7 0.617165
7 2 4 8 -0.239830
8 3 1 9 -0.876789
9 3 2 10 0.656436
10 3 3 11 -0.471325
11 3 4 12 -1.465787
12 4 1 13 -0.495308
13 4 2 14 -0.266914
14 4 3 15 -0.305884
15 4 4 16 0.546730
I can't seem to find any examples.
I think you just want a factor plot:
import numpy
import pandas
import seaborn
blocks = 3
conditions = 4
trials = 12
ndatapoints = blocks * conditions * trials
blockcol = list(range(1, blocks + 1)) * (conditions * trials)
concol = list(range(1, conditions + 1)) * (blocks * trials)
trialcol = list(range(1, trials + 1)) * (blocks * conditions)
valcol = numpy.random.normal(0, 1, ndatapoints)
fg = pandas.DataFrame({
'blocks': blockcol,
'condition': concol,
'trial': trialcol,
'value': valcol
}).pipe(
(seaborn.factorplot, 'data'),
x='blocks', y='value', hue='condition',
kind='box'
)

3D Plot after using for loop and range (Python)

i have some questions for which i couldn't find any answers although i looked up for it.
My code so far is the following:
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from math import *
from scipy.special import *
import matplotlib.pyplot as plt
import numpy as np
## Definition der Parameter für Druckgleichung nach Rudnicki (1986) ##
q = 6.0/1000
lameu = 11.2*10**9
lame = 8.4*10**9
pi
alpha = 0.65
G = 8.4*10**9
k = 1.0e-15
eta = 0.001
t = 1000*365*24600
kappa = k/eta
print "kappa ist:",kappa
c = ((kappa*(lameu-lame)*(lame+2*G))/((alpha**2)*(lameu+2*G)))
print "c ist:",c
xmin = -10
xmax = 10
ymin = -10
ymax = 10
for x in range (xmin,xmax):
for y in range (ymin,ymax):
r=sqrt(x**2+y**2)
P=(q/(rhof*4*pi*kappa))*(expn(1,r**2/(4*c*t)))
z = P/1e6
print x, y, z
x, y = np.meshgrid(x, y)
## Plotting in 3D ##
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(x, y, z, rstride=1, cstride=1, cmap=cm.jet, linewidth=0,
antialiased=False, vmin=np.nanmin(z), vmax=np.nanmax(z))
fig.colorbar(surf, shrink=0.5, aspect=5)
## Achsenskalen ##
ax.set_xlim(xmin,xmax) # x-Achsenskala vorgeben
ax.set_ylim(ymin,ymax) # y-Achsenskala vorgeben
## Beschriftung der Achsen ##
ax.set_title('Druckverteilung')
ax.set_xlabel('Distanz zu Well [m]')
ax.set_ylabel('Distanz zu Well [m]')
ax.set_zlabel('Druck in [MPa]')
plt.show()
If i try to run the program, my values for x,y and z show up as intended, but i dont get any 3D Plot. I had this issue once before, so i tried so define my infinite values for z to be treated as not a number:
z[z==np.inf] = np.nan
After adding this to my code, i get the following error:
TypeError: 'numpy.float64' object does not support item assignment
What exactly means this? I dont get it in the context. I think i need it for my plot?
Whats the exact difference in my for loop, e.g. using:
for x in range [-10,10]
and
for x in range (-10,10)
?
I know there are types of functions using
P[x,y]=....
instead of only
P=....
?
When do i have to use the brackets?
I hope someone can lighten me up. Thanks!
To answer your various questions:
z[z==np.inf] = np.nan
After adding this to my code, i get the following error: TypeError: 'numpy.float64' object does not
support item assignment
This is because z is just a number, not an array.
The () and [] confusion is simple, you access elements of a list (or any other container class implementing __getitem__ using the [] brackets. You call objects using ().
Essentially, these two bits of syntax are short forms of the less conveneient versions;
myObject[key] results in myObject.__getitem__(key), and myObject(variable) results in myObject.__call__(variable). It's just syntax.
Typically, these are used to create functions and container classes (you could misuse them, but it would make for some very confusing code).
As for making your plotting work, you're going to want to make your z array of data points, with the correct shape.
The issue you were having is that you did not provide the data to plot_surface as it requires, it needs 2D arrays of data. XX and YY are just what numpy.meshgrid creates, iirc, x and y arguments can just be straight lists, but i haven't tried it.
At any rate, you normally have elements lookign like this (for a square grid):
XX
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
YY
1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5
6 6 6 6 6 6 6 6 6
7 7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9 9
and then ZZ is just the z vaules for the function at the corresponding point, i.e. if you're plotting some function, f(x,y) then you could do something like:
for i in range(len(XX)):
for j in range(len(XX[0])):
ZZ[i][j] = f(XX[i][j], YY[i][j])
Although there is likely some much faster numpy way to do the array operations that would be faster.
i normally do something like this:
import numpy
# other boiler plae variable definitions you have
xs = numpy.linspace(xStart, xStop, num=50)
ys = numpy.linspace(yStart, yStop, num=50)
XX, YY = numpy.meshgrid(xs,ys)
ZZ = numpy.zeros_like(XX)
for i, x in enumerate(xs):
for j, y in enumerate(ys):
r=sqrt(x**2+y**2)
P=(q/(rhof*4*pi*kappa))*(expn(1,r**2/(4*c*t)))
ZZ[i][j] = P/1e6
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(XX, YY, ZZ, rstride=1, cstride=1, cmap=cm.jet, linewidth=0,
antialiased=False, vmin=np.nanmin(ZZ), vmax=np.nanmax(ZZ))
fig.colorbar(surf, shrink=0.5, aspect=5)

How to draw bar in python

I want to draw bar chart for below data:
4 1406575305 4
4 -220936570 2
4 2127249516 2
5 -1047108451 4
5 767099153 2
5 1980251728 2
5 -2015783241 2
6 -402215764 2
7 927697904 2
7 -631487113 2
7 329714360 2
7 1905727440 2
8 1417432814 2
8 1906874956 2
8 -1959144411 2
9 859830686 2
9 -1575740934 2
9 -1492701645 2
9 -539934491 2
9 -756482330 2
10 1273377106 2
10 -540812264 2
10 318171673 2
The 1st column is the x-axis and the 3rd column is for y-axis. Multiple data exist for same x-axis value. For example,
4 1406575305 4
4 -220936570 2
4 2127249516 2
This means three bars for 4 value of x-axis and each of bar is labelled with tag(the value in middle column). The sample bar chart is like:
http://matplotlib.org/examples/pylab_examples/barchart_demo.html
I am using matplotlib.pyplot and np. Thanks..
I followed the tutorial you linked to, but it's a bit tricky to shift them by a nonuniform amount:
import numpy as np
import matplotlib.pyplot as plt
x, label, y = np.genfromtxt('tmp.txt', dtype=int, unpack=True)
ux, uidx, uinv = np.unique(x, return_index=True, return_inverse=True)
max_width = np.bincount(x).max()
bar_width = 1/(max_width + 0.5)
locs = x.astype(float)
shifted = []
for i in range(max_width):
where = np.setdiff1d(uidx + i, shifted)
locs[where[where<len(locs)]] += i*bar_width
shifted = np.concatenate([shifted, where])
plt.bar(locs, y, bar_width)
If you want you can label them with the second column instead of x:
plt.xticks(locs + bar_width/2, label, rotation=-90)
I'll leave doing both of them as an exercise to the reader (mainly because I have no idea how you want them to show up).

tilted axis 2D plot where x y axis make 60 degree rather than 90

I want to plot a distribution in hexagonal lattice like following.
I want to present this data as 2D colormap or bar chart. Does any one know how to do this? I am familiar with octave, python, gnuplot, excel, matlab.
1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3
2 2 2 2 2 2 2 2 2
1 1 1 1 1 1 1 1
Here is a solution using patch in MATLAB.
data = cellfun(#(x) textscan(x, '%f')', importdata('data.txt', sprintf('\n')));
rowLen = cellfun(#numel, data);
nPoints = sum(rowLen);
centerCells = arrayfun(#(l,r) [(-l+1:2:l-1)'*sin(pi/3) -r*1.5*ones(l,1)], ...
rowLen', 1:numel(rowLen), 'UniformOutput', false);
centers = vertcat(centerCells{:});
hx = linspace(0,2*pi,7)';
vertices = reshape(...
bsxfun(#plus, permute(sin([hx pi/2+hx]), [1 3 2]), ...
permute(centers, [3 1 2])), 7 * nPoints, 2);
faces = reshape(1:7*nPoints, 7, nPoints)';
colorData = vertcat(data{:});
patch('Vertices', vertices, 'Faces', faces, ...
'FaceColor', 'flat', 'FaceVertexCData', colorData);
axis equal
and this produces
Read the documentation if you need to change the color scheme.

Categories

Resources