I get a really ugly plot using trisurf. I would like that the steep curve connecting the 0 value with the 1 value (z can be only 0 or 1) hadn't the weird orange triangles that appear in my plot:
Without cmap is even worse:
I would be expecting something like this:
but with my range of x,y (they form like a circle, as you can see in the previous plot). How can I do it?
You can download the data used to make the plot here.
My code is really basic:
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
N, theta, omega, position, A = np.loadtxt('features.txt', unpack=True)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
my_cmap = plt.get_cmap('hot')
ax.plot_trisurf(theta, omega, A, cmap = my_cmap, antialiased=True)
plt.show()
Related
I am plotting a yellow surface using Python with color='yellow', here is the codes that I wrote:
import matplotlib.pyplot as plt
import numpy as np
import math
from mpl_toolkits import mplot3d
#Below is the actual plot:
#============================================================================
fig = plt.figure(figsize=(20,10))
ax = fig.add_subplot(1,1,1, projection='3d')
x = np.arange(0,10)
y = np.arange(0,10)
X,Y = np.meshgrid(x,y)
Z = -X**2-Y**2
ax.plot_surface(X, Y, Z, color='yellow', alpha=.5)
However, what I obtained is a yellow surface looks like this: enter image description here,
which does not look very yellow.
The yellow color that I am intended to get for the surface should look like this: enter image description here, which could be easily obtained in 2d plots. However, it seems to me that I am unable to obtain this color in 3d surface plots.
Is there any way that I could obtain the normal yellow in the 3d plots? Many thanks in advance for any help and advice!
Try replacing the color string "yellow" in this line:
ax.plot_surface(X, Y, Z, color='yellow', alpha=.5)
with this:
ax.plot_surface(X, Y, Z, color='#fcfc03', alpha=.8)
Note the alpha value changed as well, which makes it less transparent but more 'yellow' visually. The alpha value affects how much you can see through it, so find a value that you like!
import matplotlib.pyplot as plt
import numpy as np
import math
from mpl_toolkits import mplot3d
#Below is the actual plot:
#============================================================================
fig = plt.figure(figsize=(20,10))
ax = fig.add_subplot(1,1,1, projection='3d')
x = np.arange(0,10,)
y = np.arange(0,10,)
X,Y = np.meshgrid(x,y)
Z = -X**2-Y**2
ax.plot_surface(X,Y,Z,color='yellow', shade=False)
you can use shade=False and you will get a nice yellow color. Hope that helps
I would like to plot my data in 3D like this figure(The filled circles are shown in gray scale based on the declination; darker colours mean lower declination.The dots in the R.A.-Dec. plane are the projection on the celestial plane)
I plot like this but I am not able to get like the given figure given above
import numpy as np, math
import matplotlib.pyplot as plt
from astropy.table import Table
from mpl_toolkits.mplot3d import Axes3D
data=Table.read('test_data.fits')
min_red=min(data['redshift'])
fig = plt.figure(figsize=(16,14))
ax = Axes3D(fig)
ax = fig.gca(projection='3d')
ax.view_init(10,30)
ax.plot(data['ra'], data['dec'], data['redshift'],'ko',markersize=5,linewidth=2)
m=ax.plot(data['ra'], data['dec'], 'ro', markersize=1, color='r', zdir='z', zs=min_red)
ax.set_xlabel('ra')
ax.set_ylabel('dec')
ax.set_zlabel('redshift')
plt.show()
But I got like this figure(the dots in Ra and Dec are the projection on the celestial plane)
How to plot like the first figure. Kindly do help
I think the easiest would be to use Axes3D.scatter as following :
import numpy as np, math
import matplotlib.pyplot as plt
from astropy.table import Table
from mpl_toolkits.mplot3d import Axes3D
data=Table.read('test_data.fits')
min_red=min(data['redshift'])
fig = plt.figure(figsize=(16,14))
ax = Axes3D(fig)
ax = fig.gca(projection='3d')
ax.view_init(10,30)
y=list(data['dec'])
ax.scatter(data['ra'], data['dec'], data['redshift'],'ko', c=y, cmap = 'Greys')
m=ax.plot(data['ra'], data['dec'], 'ro', markersize=1, color='r', zdir='z', zs=min_red)
ax.set_xlabel('ra')
ax.set_ylabel('dec')
ax.set_zlabel('redshift')
plt.show()
As specified in Axes3D.scatter documentation :
A color. c can be a single color format string, or a sequence of color specifications of length N, or a sequence of N numbers to be mapped to colors using the cmap and norm specified via kwargs (see below). Note that c should not be a single numeric RGB or RGBA sequence because that is indistinguishable from an array of values to be colormapped. c can be a 2-D array in which the rows are RGB or RGBA, however, including the case of a single row to specify the same color for all points.
My result with the code above
I'm trying to plot a wave function over one dimension but it has real and imaginary parts, so I did a 3D plot animation of it. This is a screenshot:
The main thing I would like to do is to spread it along the x-axis (which now is vertical) so it doesn't look squeezed. Also, it would be nice to set it up in a set of 3 RGB axes that intersect at the point (0,0,0). In the documentation I couldn't find any straight forward way to do this. I'm attaching the part of the code I'm using to animate it:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import mpl_toolkits.mplot3d.axes3d as p3
fig = plt.figure()
ax = fig.gca(projection='3d')
line, = ax.plot(REAL[0,:],IMAG[0,:],x,"r",linewidth=0.5)
def animacio(i):
ax.collections.clear()
line.set_data(REAL[i,:],IMAG[i,:])
line.set_3d_properties(x, 'z')
return line,
ani = animation.FuncAnimation(fig,animacio,interval=50, frames=Nt,repeat=True)
nom = 'EvoluciĆ³_'
ani.save(str(nom)+'['+str(V0)+','+str(L)+','+str(l)+','+str(xi)+','+str(sigmax)+','+str(T)+']'+'.mp4', writer="ffmpeg", dpi=300)
plt.show()
print('Animation saved as: '+str(nom)+'['+str(V0)+','+str(L)+','+str(l)+','+str(xi)+','+str(sigmax)+','+str(T)+']'+'.mp4')
You can add colored lines to the plot, just by giving start and end points and assigning a color. The limits for the 'up'-axis can be set by ax.set_zlim. I created a demo curve that roughly resembles yours.
import numpy as np
from mpl_toolkits import mplot3d
import matplotlib.pyplot as plt
x = np.linspace(-10, 10, 1000)
y = np.sin(10*x)/(x*x+1)
z = np.cos(10*x)/(x*x+1)
ax = plt.axes(projection='3d')
ax.plot3D([0,0], [0,0], [-10,10], color='crimson')
ax.plot3D([0,0], [-1,1], [0,0], color='limegreen')
ax.plot3D([-1,1], [0,0], [0,0], color='dodgerblue')
line, = ax.plot3D(y, z, x, color='blueviolet')
ax.set_zlim(-1, 1)
plt.show()
At the left the plot without limiting, at the right with limits:
To get a more elongated view, you could use something like:
plt.gcf().set_size_inches(4, 12)
I am (numerically) solving the Lorenz System by using different methods. I am plotting it using matplotlib but I would like a way to distinguish better the points.
For example:
Let's assume the points to be plotted are stored in the array a which has the form
array([[ 0.5 , 0.5 , 0.5 ],
[ 0.50640425, 0.6324552 , 0.48965064]])
#...
Now these lines of code
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(a[:,0],a[:,1],a[:,2])
plt.show()
produce:
Not very descriptive, is it? So I thought plotting discrete points would work better. So these ones:
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(a[:,0],a[:,1],a[:,2], s=0.2)
plt.show()
produce:
But it is not as descriptive as I want. I want to know what is the most descriptive way to plot the Lorenz system.
Consider making your scatter points transparent. You can do this by passing an alpha keyword to plt.scatter. Here's an example, modified from mplot3d example gallery, with alpha = 1.0, which is the default value:
ax.scatter(xs, ys, zs, alpha=1.0, s=0.2)
And here is the same scatter point cloud drawn with alpha = 0.1:
ax.scatter(xs, ys, zs, alpha=0.1, s=0.2)
Note that while this appears to be a good visualization, the interactive part of it is quite slow for a large number of points. If you really need fast performance, consider an alternative approach - splitting the lines in segments and coloring them by index, similarly to what's being done here.
I am making a polar scatter plot for a college project with matplotlib and I can't find out how to add a label to the radial axis. Here is my code ( I left out the data because it was read out of a csv)
import matplotlib.pyplot as plt
ax = plt.subplot(111, polar=True)
ax.set_rmax(1)
c = plt.scatter(theta, radii)
ax.set_title("Spread of Abell Cluster Supernova Events as a Function of Fractional Radius", va='bottom')
ax.legend(['Supernova'])
plt.show()
(My plot looks like this. I can't seem to find any straight forward method to do it. Has anyone dealt with this before and have any suggestions?
I don't know of a built in way to do it, but you could use ax.text to make your own. You can get the position of the radial tick labels using ax.get_rlabel_position(), and the mid point of the radial axis using ax.get_rmax()/2.
For example, here's your code (with some random data):
import matplotlib.pyplot as plt
import numpy as np
theta=np.random.rand(40)*np.pi*2.
radii=np.random.rand(40)
ax = plt.subplot(111, polar=True)
ax.set_rmax(1)
c = plt.scatter(theta, radii)
ax.set_title("Spread of Abell Cluster Supernova Events as a Function of Fractional Radius", va='bottom')
ax.legend(['Supernova'])
label_position=ax.get_rlabel_position()
ax.text(np.radians(label_position+10),ax.get_rmax()/2.,'My label',
rotation=label_position,ha='center',va='center')
plt.show()
And here's the output:
I'd be interested to see if there's a more elegant solution, but hopefully this helps you.
from pylab import *
N = 150
r = 2*rand(N)
theta = 2*pi*rand(N)
area = 200*r**2*rand(N)
colors = theta
ax = subplot(111, polar=True)
c = scatter(theta, r, c=colors, s=area, cmap=cm.hsv)
c.set_alpha(0.75)
ax.set_ylabel('Radius', rotation=45, size=11)
show()
A slightly different method from #tom. This uses directly the plt.legend option.
Example:
import matplotlib.pyplot as plt
import numpy as np
theta=np.random.rand(40)*np.pi*2.
radii=np.random.rand(40)
ax = plt.subplot(111, polar=True)
ax.set_rmax(1)
c = plt.scatter(theta, radii,label='Supernova')
ax.set_title("Spread of Abell Cluster Supernova Events as a Function of Fractional Radius", va='bottom')
ax.legend(loc='lower right', scatterpoints=1)
plt.show()
You can change lower right to upper right or even to best to leave the alignment of the legend to matplotlib.