Polar chart issue in Python, angles not being taken into account - python

I am having some trouble with a polar chart I am working on. The figure I should get is an eight-shape (some friends of mine plotted the data in Origin and Excel and it does work), but it looks like the code is not properly written. By looking at the figure, I see that the code is not taking into account the angles I am writing (theta array), but I don't know why it happens. I've already tried some more codes and writing the angles in radians, but nothing seems to work.
import numpy as np
import matplotlib.pyplot as plt
from pylab import *
import matplotlib.pyplot as plt
from pylab import *
import numpy as np
r = np.array([11.7,12.1,10.1,6.6,3.1,1.5,2.3,5.2,
8.7,11.5,12,10.1,6.6,3.3,1.5,2.3,5.3,9.2,11.9])
theta =np.array([0,20,40,60,80,100,120,140,160,180,
200,220,240,260,280,300,320,340,360])
ax = plt.subplot(111, projection='polar')
ax.plot(theta,r)
ax.set_rmax(13)
ax.set_rticks([2,4,6,8,10,12]) # less radial ticks
ax.set_rlabel_position(-40) # get radial labels away from plotted line
ax.grid(True)
ax.set_title("A line plot on a polar axis", va='bottom')
plt.show()
I've also tried this:
r3 = np.array([11.7,12.1,10.1,6.6,3.1,1.5,2.3,5.2,
8.7,11.5,12,10.1,6.6,3.3,1.5,2.3,5.3,9.2,11.9])
theta3 =np.array([0,20,40,60,80,100,120,140,160,180,
200,220,240,260,280,300,320,340,360])
fig = plt.figure()
ax = fig.add_subplot(111, projection='polar')
c = ax.scatter(theta3, r3)

Counter-intuitively, while the polar plot shows its theta axis in degrees, it actually expects the coordinates to be in radians:
import numpy as np
import matplotlib.pyplot as plt
r = np.array([11.7,12.1,10.1,6.6,3.1,1.5,2.3,5.2,
8.7,11.5,12,10.1,6.6,3.3,1.5,2.3,5.3,9.2,11.9])
theta =np.array([0,20,40,60,80,100,120,140,160,180,
200,220,240,260,280,300,320,340,360], dtype=float) # making sure it is float
# convert to radians
# theta *= np.pi/180.
theta = np.deg2rad(theta)
ax = plt.subplot(111, projection='polar')
ax.plot(theta,r)
ax.grid(True)
ax.set_title("A line plot on a polar axis", va='bottom')
plt.show()
I have not managed to find any place in the documentation, where this is explicitly stated (only examples where it is done correctly).
The weird pictures you got came from the fact that all values above 2pi are folded back into the range 0...2pi. So e.g. 20 % 2pi = 1.15, which is about 65 degrees when converted, which is where the second value is actually located in your plot.

Related

Reorient Matplotlib polar plot

I would like to produce a polar scatterplot in matplotlib. The plot I have from using ax1 = plt.subplot(111, polar=True) looks fine, but I need to deviate from the usual polar graph orientation.
I need 0 degrees to point straight up (rotation).
I need 90 degrees to point right (mirror image).
(How) Can I do this?
You need ax.set_theta_zero_location and ax.set_theta_direction.
For details, see the doc
import matplotlib.pyplot as plt
import numpy as np
r = range(360)
angles = [i * np.pi / 180 for i in r]
f = plt.figure()
ax = plt.subplot(polar=True)
plt.polar(angles, r)
ax.set_xticks(angles[::10])
ax.set_theta_zero_location("N")
ax.set_theta_direction(-1)
plt.show()

Mayavi - hide "diagonal" lines in wireframe

I've just started using mayavi and was wondering if there's a way to plot the wireframe representation of the surface that looks like the one I'm used from matplotlib 3d.
Minimal example:
# sphere example
import numpy as np
from mayavi import mlab
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# azimut and polar angle
phi = np.linspace(0,2*np.pi,10)
theta = np.linspace(0,np.pi,10)
phi, theta = np.meshgrid(phi,theta)
# cartesian coordinates
x = np.cos(phi)*np.sin(theta)
y = np.sin(phi)*np.sin(theta)
z = np.cos(theta)
#plotting using matplotlib
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_wireframe(x,y,z)
#plotting using mayavi
mlab.mesh(x,y,z,representation='wireframe', color=(0,0,1))
As you can see the outputs differ: matplotlib prints the lines with constant phi resp theta. Mayavi however, also prints diagonal lines (highlighted in yellow) connecting those paths.
I prefer the matplotlib version. Is there a way to achieve the same wireframe with mayavi?
TIA
Use mlab.surface() instead of mlab.mesh()

Matplotlib: Plot 2d array radially to make 3d Scatterplot

I am looking to make a plot similar to the one found here, with the simple difference that I would like to to set the distance from the center for each point. Ie, given a slice of the plot is a circle, where I would like each of the points to be at a definable distance from the center.
What I a starting with, given a simple modification of the previously mentioned answer:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib
import numpy as np
from scipy.interpolate import interp1d
from matplotlib import cm
from matplotlib import pyplot as plt
step = 0.04
maxval = 1.0
fig = plt.figure()
ax = Axes3D(fig)
# u here would define the desired distance from radial axis
# u=np.array([0,1,2,1,0,2,4,6,4,2,1])
v=np.array([4,4,6,3,6,4,1,4,4,4,4])
r=np.array([0,1,2,3,4,5,6,7,8,9,10])
f=interp1d(r,u)
# walk along the circle
p = np.linspace(0,2*np.pi,len(r))
R,P = np.meshgrid(r,p)
# transform them to cartesian system
X,Y = R*np.cos(P),R*np.sin(P)
Z=f(R)
ax.scatter(X, Y, Z)#, rstride=1, cstride=1, cmap=cm.jet)
ax.set_xticks([])
fig.savefig(str(output_prefix + '3d..png'), dpi=(200))
What I would like to plot (apologies for the blurred sketch):
I have tried using interp2d to add the u variable commented out above, but no luck. Changing Z to the array u threw the error that X, Y, and Z must be the same size ("Argument 'zs' must be of same size as 'xs' ", understandably as X and Y are now interpolated) What do I need to do? Any tips would be appreciated!
I don't know exactly what you meant in your question.
I made v to be the offset of the center of the circles in x-axis.
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
from scipy.interpolate import interp1d
from matplotlib import pyplot as plt
step = 0.04
maxval = 1.0
fig = plt.figure()
ax = Axes3D(fig)
# v here would define the desired distance from radial axis
u=np.array([0,1,2,1,0,2,4,6,4,2,1])
v=np.array([4,4,6,3,6,4,1,4,4,4,4])
r=np.array([0,1,2,3,4,5,6,7,8,9,10])
f=interp1d(r,u)
# walk along the circle
V = np.tile(v, (len(u), 1))
p = np.linspace(0,2*np.pi,len(r))
R,P = np.meshgrid(r,p)
# transform them to cartesian system
X,Y = V + R*np.cos(P),R*np.sin(P)
Z=f(R)
ax.scatter(X, Y, Z)#, rstride=1, cstride=1, cmap=cm.jet)
ax.set_xticks([])
plt.show()

Python - color a 3d line plot

I have a 3d line plot of the solar spectrum, which I plotted using the command,
from mpl_toolkits.mplot3d.axes3d import Axes3D
from matplotlib.collections import PolyCollection, LineCollection
from matplotlib.colors import colorConverter, ListedColormap, BoundaryNorm
import matplotlib.cm as cm
fig = plt.figure(figsize(15, 8))
ax = fig.gca(projection='3d')
x = SpectrumDF['Wavelength']
z = SpectrumDF['DNI']
y = SpectrumDF['TESTNUM']
ax.plot(x, y, z)
ax.set_xlabel('Wavelength')
ax.set_ylabel('Test Number')
ax.set_zlabel('Intensity')
The resultant plot is solid blue and takes whichever individual color I give in the function: plot( ).
I have been trying to create a color gradient along the z-axis, intensity, without any success.
I have around 500 test numbers, each has 744 data points.
Thank you for the help!
This wouldn't let me post images because I don't have enough reputation. Anyway, here's the link to the plot I get using this code https://plus.google.com/106871046257785761571/posts/fMYsDF5wAQa
Using the example - Line colour of 3D parametric curve in python's matplotlib.pyplot - I got a scatter plot with color gradient along the z axis - here's the link to the image of that plot - https://plus.google.com/u/0/106871046257785761571/posts/SHTsntgQxTw?pid=6133159284332945618&oid=106871046257785761571
I used the following command:
fig = plt.figure(figsize(15,8))
ax = fig.gca(projection='3d')
x = FilteredDF['Wavelength']
z = FilteredDF['DNI']
y = FilteredDF['TESTNUM']
ax.scatter(x, y, z, c=plt.cm.jet(z/max(z)))
ax.set_xlabel('Wavelength')
ax.set_ylabel('Test Number')
ax.set_zlabel('Intensity')
plt.show()
I am still working on getting a colored line plot because I have a lot of points, which makes scatter plot very slow to work with.
Thank you

plot many circles based on x,y,r being vectors in python

x,y are positions of the circles and r is the radius - all vectors.I want to plot them all at once. Something like:
import matplotlib.pyplot as plt
from matplotlib.patches Circle
#define x,y,r vectors
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
plt.Circle((x,y),r,color='r')
plt.show()
Thanks.
plt.scatter allows you to define a radius of the points plotted.
From the doc
matplotlib.pyplot.scatter(x, y, s=20, c='b', marker='o')
[...]
s:
size in points^2. It is a scalar or an array of the same length as x and y.
Playing with facecolor and edgecolor you should be able to get what you want
You can find an example in How to set_gid() for each bubble in matplot scatter chart?
I am not informed about the Circles patch, but here is how you can do it with the standard plot command:
import numpy as np
import matplotlib.pyplot as plt
x = np.array([0.2,0.4])
y = np.array([0.2,1.2])
r = np.array([0.5,0.3])
phi = np.linspace(0.0,2*np.pi,100)
na=np.newaxis
# the first axis of these arrays varies the angle,
# the second varies the circles
x_line = x[na,:]+r[na,:]*np.sin(phi[:,na])
y_line = y[na,:]+r[na,:]*np.cos(phi[:,na])
plt.plot(x_line,y_line,'-')
plt.show()
The basic idea is to give the plt.plot(...) command two 2D arrays. In that case they are interpreted as a list of plots. Espacially for many plots (=many circles) this is much faster, than plotting circle by circle.

Categories

Resources