plotting data in python from 2D to 3D - python

I have a bunch of data that I need to see in some understandable manner. here what I've done so far:
..................................
features = []
for i in range(len(variance_list[0][:])):
for j in range(len(variance_list)):
features.append(variance_list[j][i])
plt.plot(features)
features.clear()
plt.xlabel('classes ')
plt.ylabel('features')
plt.show()
The result looks as followed:
So I've tried to plot this in 3D as followed :
for i in range(len(variance_list[0][:])):
for j in range(len(variance_list)):
Axes3D.plot(i,j,variance_list[j][i],label='parametric curve')
plt.show()
I get the following error message:
1510 # many other traditional positional arguments occur
1511 # such as the color, linestyle and/or marker.
-> 1512 had_data = self.has_data()
1513 zs = kwargs.pop('zs', 0)
1514 zdir = kwargs.pop('zdir', 'z')
AttributeError: 'int' object has no attribute 'has_data'
Any idea what I'm missing, or how may I solve this

in addition to cosmos' suggestion, there is a difference in x,y lines and the z var
variance_list=[[np.random.rand()**2*(j+1) for _ in range(10)] for j in range(4)]
fig = plt.figure()
ax = fig.gca(projection='3d')
for j in range(len(variance_list)):
ax.plot(range(len(variance_list[0])),variance_list[j],j,label='parametric curve')
plt.show()

instead of Axes3D.plot it should be:
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot(...)
according to mplot3d docs

Related

How can I use the 'xy' mode in a 3d matplolib quiver plot?

I have been trying to plot a 3d graph a gradient field on matplotlib. However, I realized that the arrows were pointing in the wrong direction and so I looked at the config of quiver. I realized about this flag 'angles' and thought that it could fix my problem. However I get the following error.
AttributeError: 'Line3DCollection' object has no property 'angles'
Here's the code
Fuerza_por_atomo_array = np.zeros(coords.shape[1])
Fuerza_por_atomo_array_vector = np.zeros(coords.shape)
for i, coord_i in enumerate(coords.T):
for j, coord_j in enumerate(coords.T):
if i != j:
Fuerza_por_atomo_array[i] -= dVdr(np.linalg.norm(coord_i-coord_j))
Fuerza_por_atomo_array_vector[:,i] -= \
dVdr(np.linalg.norm(coord_i-coord_j)) * np.array([drdx(coord_i[k]-coord_j[k], np.linalg.norm(coord_i-coord_j)) for k in range(3)]) # Regla de la cadena
X, Y, Z = coords[0,:], coords[1,:], coords[2,:]
fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
lat = np.tile(np.linspace(-90, 90, 192), 50)
ax.scatter(coords[0,:], coords[1,:], coords[2,:], c=E_por_atomo, cmap=plt.get_cmap("hot"), marker="o")
plt.quiver(X, Y, Z, Fuerza_por_atomo_array_vector[0,:], Fuerza_por_atomo_array_vector[1,:], Fuerza_por_atomo_array_vector[2,:], length=3, angles="xy")
#ax.set_xlim(-1, x_num); ax.set_zlim(-1, z_num); ax.set_ylim(-1, y_num)
plt.colorbar(mappable=cm.ScalarMappable(\
norm=colors.Normalize(vmin=np.min(E_por_atomo), vmax=np.max(E_por_atomo), clip=False), \
cmap=plt.get_cmap("hot")), \
location='top', ax=ax)
ax.set_xlabel("X") ;ax.set_ylabel("Y"); ax.set_zlabel("Z")
fig.tight_layout()
plt.show()
coords is a (3,N)-array with 3d point coordinates and dVdr is just a numerical funcion, a derivative might say. If this is not the place for such a question, don't be hesitant to expose it.

Pyplot Errorbars with different x- and y-error

I am trying to create an errorbar plot with different x- and y-errors. Let's say i have the following data:
x = [[item%20 for item in reversed(range(50,55))] for _ in range(13)]
y = [[item%20 for item in reversed(range(20,25))] for _ in range(13)]
fig, ax = plt.subplots()
ax.set_xscale('log')
for i in range(len(x)):
plt.errorbar(x=[x[0][i]], y=[y[0][i]], xerr=x[i][1:3], yerr=y[i][1:3], ls='None', label='B{}D{}'.format(x[i][3],y[i][4]))
plt.legend(prop={'size': 6})
Now this will create an error:
ValueError: err must be [ scalar | N, Nx1 or 2xN array-like ]
However, I do not understand this error, as my error has the shape (2, N=1), just like ma data is N=1.
When I transpose my data and plot it, it works just fine, but I want to plot every datapoint with a different labelm marker and color.
For me it would also be okay to plot all errorbars at once and change the colors, markers and assign a label afterwards, however I do not know how to do so. However, I believe that I am doing a simple mistake which would make that approach unnecessary.
Any help is highly appreciated :)
if you are plotting one point at a time, your errors should be shaped (2,1), not (2,) as they are in your code.
Furthermore, I think you had an error in the way you were getting your x,y values.
x = [[item for item in reversed(range(50,55))] for _ in range(13)]
y = [[item for item in reversed(range(20,25))] for _ in range(13)]
fig, ax = plt.subplots()
ax.set_xscale('log')
for i in range(len(x)):
X = x[i][0]
Y = y[i][0]
dx = np.array(x[i][1:3]).reshape((2,1))
dy = np.array(y[i][1:3]).reshape((2,1))
print(X,Y,dx,dy)
plt.errorbar(x=X, y=Y, xerr=dx, yerr=dy, ls='None', label='B{}D{}'.format(x[i][3],y[i][4]))
plt.legend(prop={'size': 6})

plotting an mXnXk matrix as a 3d model in python

I have a matrix generated by parsing a file the numpy array is the size 101X101X41 and each entry has a value which represents the magnitude at each point.
Now what I want to do is to plot it in a 3d plot where the 4th dimension will be represented by color. so that I will be able to see the shape of the data points (represent molecular orbitals) and deduce its magnitude at that point.
If I plot each slice of data I get the desired outcome, but in a 2d with the 3rd dimension as the color.
Is there a way to plot this model in python using Matplotlib or equivalent library
Thanks
EDIT:
Im trying to get the question clearer to what I desire.
Ive tried the solution suggested but ive received the following plot:
as one can see, due to the fact the the mesh has lots of zeros in it it "hide" the 3d orbitals. in the following plot one can see a slice of the data, where I get the following plot:
So as you can see I have a certain structure I desire to show in the plot.
my question is, is there a way to plot only the structure and ignore the zeroes such that they won't "hide" the structure.
the code I used to generate the plots:
x = np.linspase(1,101,101)
y = np.linspase(1,101,101)
z = np.linspase(1,101,101)
xx,yy,zz = np.meshgrid(x,y,z)
fig=plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(xx, yy, zz, c=cube.calc_data.flatten())
plt.show()
plt.imshow(cube.calc_data[:,:,11],cmap='jet')
plt.show()
Hope that now the question is much clearer, and that you'd appreciate the question enough now to upvote
Thanks.
you can perform the following:
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
epsilon = 2.5e-2 # threshold
height, width, depth = data.shape
global_min = np.inf
global_max = -np.inf
for d in range(depth):
slice = data[:, :, d]
minima = slice.min()
if (minima < global_min): global_min = minima
maxima = slice.max()
if (maxima>global_max): global_max=maxima
norm = colors.Normalize(vmin=minima, vmax=maxima, clip=True)
mapper = cm.ScalarMappable(norm=norm, cmap=cm.jet)
points_gt_epsilon = np.where(slice >= epsilon)
ax.scatter(points_gt_epsilon[0], points_gt_epsilon[1], d,
c=mapper.to_rgba(data[points_gt_epsilon[0],points_gt_epsilon[1],d]), alpha=0.015, cmap=cm.jet)
points_lt_epsilon = np.where(slice <= -epsilon)
ax.scatter(points_lt_epsilon[0], points_lt_epsilon[1], d,
c=mapper.to_rgba(data[points_lt_epsilon[0], points_lt_epsilon[1], d]), alpha=0.015, cmap=cm.jet)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.title('Electron Density Prob.')
norm = colors.Normalize(vmin=global_min, vmax=global_max, clip=True)
cax, _ = colorbar.make_axes(ax)
colorbar.ColorbarBase(cax, cmap=cm.jet,norm=norm)
plt.savefig('test.png')
plt.clf()
What this piece of code does is going slice by slice from the data matrix and for each scatter plot only the points desired (depend on epsilon).
in this case you avoid plotting a lot of zeros that 'hide' your model, using your words.
Hope this helps
You can adjust the color and size of the markers for the scatter. So for example you can filter out all markers below a certain threshold by putting their size to 0. You can also make the size of the marker adaptive to the field strength.
As an example:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
f = lambda x,y,z: np.exp(-(x-3)**2-(y-3)**2-(z-1)**2) - \
np.exp(-(x+3)**2-(y+3)**2-(z+1)**2)
t1 = np.linspace(-6,6,101)
t2 = np.linspace(-3,3,41)
# Data of shape 101,101,41
data = f(*np.meshgrid(t1,t1,t2))
print(data.shape)
# Coordinates
x = np.linspace(1,101,101)
y = np.linspace(1,101,101)
z = np.linspace(1,101,41)
xx,yy,zz = np.meshgrid(x,y,z)
fig=plt.figure()
ax = fig.add_subplot(111, projection='3d')
s = np.abs(data/data.max())**2*25
s[np.abs(data) < 0.05] = 0
ax.scatter(xx, yy, zz, s=s, c=data.flatten(), linewidth=0, cmap="jet", alpha=.5)
plt.show()

Python visualizing optimization parameters

I have the following code where I iterate through a grid of 2 parameters in order to see which set of parameters will yield the best result.
from sklearn.grid_search import ParameterGrid
ar1= np.arange(1,10,0.1)
ar2= np.arange(0.1,3,0.01)
param_grid = {'p1': ar1, 'p2' : ar2}
grid = ParameterGrid(param_grid)
result=[]
p1=[]
p2=[]
for params in grid:
r = getresult(params['p1'], params['p2'])
result.append(r)
p1.append(params['p1'])
p2.append(params['p2'])
As a result I get 3 arrays, one with the result of every iteration and two arrays (p1,p2) with the corresponding parameters. I would now like to plot this data with matplotlib to visualize how the result varies across the parameter plane.
I tried the following but i got a blank plot:
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(p1, p2, result)
Ideally I would like to be able to create something like the plot below. How can I accomplish this with matplotlib?
I ended up going with the following solution:
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_trisurf(X, Y, Z, cmap=cm.jet, linewidth=0)
fig.tight_layout()
plt.show()
The above yielded the desired visualization, as seen below:
plot_surface requires the input arrays to be two-dimensional. As I interprete it, your arrays are 1D. So reshaping them into 2D could be a solution.
import numpy as np
shape = (len(ar2), len(ar1))
p1 = np.array(p1).reshape(shape)
p2 = np.array(p2).reshape(shape)
result = result.reshape(shape)
Then plotting it via
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(p1, p2, result)
might work. (I cannot test it at the moment.)

matplotlib rc colorcycle argument with scatterplot

i have configured my own colorcycle in my rc-file (axes.color_cycle) which works fine for the plot command but not for something like:
for i in range(len(x)):
ax.scatter(x[i],y[i],s=area[i], alpha = 0.5)
any ideas how to fix that ?
You dont need to loop in order to use .scatter. You can prepare a list of colors and provide it with color= to scatter. The color method is implemented in such a way that the list of colors does not need to match the length of the data, it gets automatically repeated/cycled or truncated if necessary.
So for example:
fig, ax = plt.subplots()
n = 50
x = np.random.randint(0,100,n)
y = np.random.randint(0,100,n)
area = np.random.randint(20,100,n)
ax.scatter(x, y, s=area, alpha=0.5, color=mpl.rcParams['axes.color_cycle'])
Results in:

Categories

Resources