I've been messing around with Mayavi for 3D graphing, and I can graph the scatter plot I want but can't seem to get the Axes to look proper. I found the following previous question that starts to get at what I'm after, but doesn't go into detail. I want a 3D scatter plot like #1 but with nice-looking axes like #2 (I'd embed but I don't have enough reputation).
The regular Mayavi Axes aren't going to cut it. Any tips for getting the planes that Matplotlib has?
This is actually pretty straightforward once we get the "trick", and I have done it many times.
The 'trick' is to generate the mayavi plot first, then transfer it into the matplotlib window where you can use all the familiar matplotlib tools to make axes with numbers, dates, arrows, or the other pieces that matplotlib provides. In this code example I'll just drop the mayavi 'copper spheres' example into a matplotlib set of axes:
import numpy, pylab, mayavi, mayavi.mlab
import matplotlib.pyplot as plt
t = numpy.linspace(0, 4 * numpy.pi, 20)
cos,sin = numpy.cos, numpy.sin
x = sin(2 * t)
y = cos(t)
z = cos(2 * t)
s = 2 + sin(t)
mayavi.mlab.points3d(x, y, z, s, colormap="copper", scale_factor=.25)
arr = mayavi.mlab.screenshot()
fig = plt.figure(figsize=(5, 5))
pylab.imshow(arr)
plt.show()
The result is just the mayavi plot in a matplotlib set of axes:
The only tricky part is that you'll need to build a working knowledge of the scales and dimensions of mayavi and matplotlib to get the two to scale together if you want to produce more than one or two manually built plots. That is non-trivial but fairly well documented for both Mayavi and Matplotlib and from the sounds of things you know both so I won't belabor those points. (Now that things are in Matplotlib you can make them part of generated PDFs too or port them into Microsoft Word with python-docx)
Related
using Python I would like to plot a curve for the function y=cosh(x)*cos(5x) in my Jupyter Notebook.
In other words:
(cosine hyperbolicus of x) times (cosine of 5x)
How do I do this?
What do I need to import?
Thank you very much in advance.
Greetings
Specify the range of values for x that you need.
You can use Seaborn on top of Matplotlib to make it prettier, but this is optional:
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-5,5,0.1) # start,stop,step
y= (np.cosh(x))*(np.cos(5*x) )
# set a grey background (use sns.set_theme() if seaborn version 0.11.0 or above)
sns.set(style="darkgrid")
plt.plot(x,y)
plt.show()
You will need to import a plotting library and a maths library. The most commonly used plotting library is matplotlib, and for maths it's numpy. For plotting, bokeh is a an alternative to matplotlib, which I think is great because graphs are interactive by default. The disadvantage is that because it's not as widely used as matplotlib, you're less likely to find help on it in terms of StackOverflow answers and tutorials.
Anyway, to the code:
# Import the necessary packages and modules
import matplotlib.pyplot as plt
import numpy as np
# Set your x-range and calculate y
xmin = -2.5
xmax = 2.5
numPoints = 100
x = np.linspace(xmin, xmax, numPoints)
y = np.cosh(x)*np.cos(5*x)
# Plot -- it really can be this simple [1]
plt.plot(x,y)
Both of the graphing libraries above give you flexible options on where to place the axes, legends, titles, and so on. I recommend searching for beginner's tutorials on them to learn this stuff in depth.
[1] There are two ways to plot in matplotlib. What is shown here is the MATLAB-like interface. The other method is to use the object-based interface, which takes a bit more of getting used to, and requires a bit more boilerplate code, but that's what you will end up using once you demand more control over the appearance of your plots.
I recommend starting with the MATLAB-like commands first. The documentation has a good beginner's tutorial: https://matplotlib.org/stable/tutorials/introductory/pyplot.html
I am aware of keras, block n a few others Python libraries for nn which do RL among others. But is there a library than can make the task of visualizations easy? In terms of 3D model of agents/environment,Seeing the simulations etc... I can see a few RL videos online that show the simulated agent/environment but either they have made visual models from the ground up or used some other language/technology...(or they are very old)
Probably you are interested in OpenAI Gym and MuJoCo for 3D environment simulation/visualization.
Generally speaking that is the difference between a 3D visualization library and 3D scientific visualization library which has a more "high-level" approach to visualization than the prior (direct calls to a scatterplot, surface, and so on).
Since you did not specify an actual example of what you want to plot I can only provide viable libraries that are considered simple (considering the 3D lib universe of Python).
One is VPython which has very explicit syntax towards 3D primitives. This would be a valid code for building a sphere and a box:
from visual import *
ball = sphere(pos=(-5,0,0), radius=0.5, color=color.cyan)
wallR = box(pos=(6,0,0), size=(0.2,12,12), color=color.green)
If your simulation rely on very well defined objects like images, surfaces, scattered points and so on you might want to take a look at the 3D capabilities of matplotlib:
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
xs = np.random.randint(0,100,100)
ys = np.random.randint(0,100,100)
zs = np.random.randint(0,100,100)
ax.scatter(xs, ys, zs, c=c)
plt.show()
Also Mayavi has a lot of high level calls to well know plots (but I think at the date I'm writing this is still not available in Python 3, someone correct me if I'm wrong):
import numpy
from mayavi.mlab import *
def test_surf():
"""Test surf on regularly spaced co-ordinates like MayaVi."""
def f(x, y):
sin, cos = numpy.sin, numpy.cos
return sin(x + y) + sin(2 * x - y) + cos(3 * x + 4 * y)
x, y = numpy.mgrid[-7.:7.05:0.1, -5.:5.05:0.05]
s = surf(x, y, f)
#cs = contour_surf(x, y, f, contour_z=0)
return s
Mayavi itself is based on VTK which also has a Python API. Other relevant libraries are:
pyQtGraph: very good if you want to embed your visualization (2D and 3D) in PySide or PyQt.
Glumpy
Vispy: It's still very new but I'm expecting great things from this library. If memory does not fail me It's being made by the same people who brought use libraries such as pyQtGraph, Glumpy and Galry.
Galry
There are others like the bindings for OpenSceneGraph, OpenGL or Coin3D but many are badly documented, or with a very tough learning curve.
As an extra you might also want to consider Blender since you can use Python inside and it has a very rich environment for 3D modeling.
I have a 3D line plot in matplotlib, created using the following code:
def view(self):
from mpl_toolkits.mplot3d import Axes3D #noqa
import matplotlib.pyplot as plt
ax = plt.figure().gca(projection='3d')
history = np.array(self.position_history)
x, y ,z = history[:, 0], history[:, 1], history[:, 2]
ax.plot(x, y, z)
plt.show()
Here history is an Mx3 array of points. This works fine and pops up a plot as expected. I am able to click and drag to modify the azimuth and elevation interactively. I am able to zoom by right-clicking and dragging.
However I am wondering if it is possible to modify the center point of the pan and zoom? I would like to zoom into the top-right, and then pan around with the top right as my center of rotation. If you have ever used solidworks or another CAD program, this is the behavior I am after. Is this doable? If not interactively, can I do it programmatically?
And finally, if none of this is possible in matplotlib, is there another library that can accomplish what I want?
I have also run into trouble in the past in terms of customizing mplot3d, rather unsuccessfully..
And finally, if none of this is possible in matplotlib, is there another library that can accomplish what I want?
you can do this with mayavi
here is a relevant stackoverflow answer for customizing how you interact with your plot
there are also various useful tips and tricks for animating in general and for using mayavi
(apologies if this isn't useful)
Not sure this will do what you need but you can define the center when you first plot. Here, "c_x" is the center of rotation on the x axis and the -/+ 200 defines the axis to be 200 units in both direction. Likewise for y and z.
If you had the user choose the center before plotting, that could work as a crude work around.
http://matplotlib.org/api/axes_api.html?highlight=set_xbound#matplotlib.axes.Axes.set_xbound
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.autoscale(enable=False,axis='both') #you will need this line to change the Z-axis
ax.set_xbound(c_x-200, c_x+200)
ax.set_ybound(c_y-200, c_y+200)
ax.set_zbound(c_z-200, c_z+200)
Is there a way of a procedure similar to plt.gca() to get a handle to the current axes. I first do a=mlab.surf(x, y, u2,warp_scale='auto')
and then
b=mlab.plot3d(yy, yy, (yy-40)**2 ,tube_radius=20.0)
but the origin of a and b are different and the plot looks incorrect. So I want to put b into the axes of a
In short, what would be the best way in mayavi to draw a surface and a line on same axes?
What you are expecting to be able to do from your matplotlib experience is not how mayavi axes work. In matplotlib the visualization is a child of the axes and the axes determines its coordinates. In mayavi or vtk, visualization sources consist of points in space. Axes are objects that surround a source and provide tick markings of the coordinate extent of those objects, that are not necessary for the visualizations, and where they exist they are children of sources.
You should remove the argument warp_scale='auto'
a=mlab.surf(x, y, u2)
and it will work.
I want to plot some (x,y) points on the same graph and I don't need any special features at all short of support for polar coordinates which would be nice but not necessary. It's mostly for visualizing my data. Is there a simple way to do this? Matplotlib seems like way more than I need right now. Are there any more basic modules available? What do You recommend?
Go with matplotlib Chance is that sometime in the future you might need to do more than just "simple" stuff and then you don't need to invest time learning a new plot-tool.
See this link for list of plotting tools for python...
Absolutely. Matplotlib is the way to go.
The pyplot module provides a nice interface to get simple plots up and running fast, especially if you are familiar with MatLab's plotting environment. Here is a simple example using pyplot:
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
x_points = xrange(0,9)
y_points = xrange(0,9)
p = ax.plot(x_points, y_points, 'b')
ax.set_xlabel('x-points')
ax.set_ylabel('y-points')
ax.set_title('Simple XY point plot')
fig.show()
import matplotlib.pyplot as plt
x = range(1,10)
y = range(1,10)
plt.plot(x,y,'o')
plt.show()
Here's a simple line with made up x, y. Note: x and y are lists.
Their lengths should be equal or you'll get a error. Cheers!
I suggest the most good looking plotting library for Python: CairoPlot
You can use the Tkinter canvas widget. It uses rectangular coordinates but of course you can translate to polar. The canvas is pretty much just like it sounds -- a blank canvas on which you can draw points, lines, circles, rectangles, etc.
You could always write a plotting function that uses the turtle module from the standard library.
MathGL is GPL plotting library which have Python interface, arbitrary (including polar) curved coordinates, a lot of plot types, export to PNG, EPS, SVG, widgets, and so on. For 1D plot samples see here.
Have you tried to use pillow?
from PIL import Image, ImageDraw
#Set up canvas
img = Image.new (mode, size)
draw = ImageDraw.Draw (img)
#Draw your points
draw.point (xy, colour)