There are lots of good open-source tools that you can use to make high-resolution, publication-quality 2D plots. Personally, I like to use Python, numpy, and matplotlib. Unfortunately, it is much harder to find a good tools to make 3D plots. Older versions of matplotlib had rudimentary 3D support, but this was removed in version 0.98. In this post, I will review a Python 3D plotting library called PyX.

## Preparing the data

Figuring out how to store the data to be plotted was actually the hardest part of learning to use PyX. The data format for 3D plots is not well documented. PyX requires a list of (x,y,z) lists like this:

[ [x0 y0 z[0,0]] [x0 y1 z[0,1]] [x0 y2 z[0,2]] ... [x1 y0 z[1,0]] [x1 y1 z[1,1]] [x1 y2 z[1,2]] ... ]

Unfortunately, PyX is designed to work with lists rather than Numpy arrays, which can be a real disadvantage for large datasets. Here is a code snippet that shows how I transformed some Numpy data into a list of lists that can be plotted in PyX. The 1D Numpy arrays z_values and theta_average contain x and y values, and the z values are stored in the 2D Numpy array called B_h_theta.

```
[sourcecode language='Python']
# Reshape data for plotting with pyx
values = []
for i in range(B_h_theta.shape[0]):
for j in range(B_h_theta.shape[1]):
values.append([z_values[i], theta_average[j], B_h_theta[i][j]])
[/sourcecode]
```

## Plotting

First create a **graph.data.points** object. The one required argument is a list of values to plot, in the form described above. There are other types of **graph.data** objects for reading data from text files, plotting functions, etc. Then, create a **graph.graphxyz** object which defines the visual appearance of the graph. Call the plot() method of **graph.graphxyz **and pass in the **data** object as an argument. Call the dodata() to finish the plot, and then call writeEPSfile() or writePDFfile() to write the plot to a file on disk. There is no way (that I found) to just show the plot in a graphical window.

```
[sourcecode language='Python']from pyx import *
v = graph.data.points(values, title="B(h,theta)", addlinenumbers=0, x=0, y=1, z=2)
g = graph.graphxyz(size=4, projector=graph.graphxyz.central(10, 150, 30),
x=graph.axis.linear(title="z"), y=graph.axis.linear(title=r'$theta$'),
z=graph.axis.linear(title="B(h,theta)"), x2=None, y2=None, z2=None)
g.plot(v, [graph.style.grid()])
g.dodata()
g.writeEPSfile("phi_plot")
[/sourcecode]
```

## Results

## Advantages

- Clean, object-oriented interface
- Produces nice surface and wireframe plots in .pdf and .eps formats
- Appears to be flexible and full-featured

## Disadvantages

- Does not seem to be actively developed or maintained (although it is very useful in its present state)
- Does not integrate easily with Numpy–all data needs to be stored in text files or Python lists
- No GUI output–writes images straight to .pdf or .eps files
- TeX labels have poor resolution (at least on my system)

Anton Daneykoi am in the middle of picking something up for the 3D vector map. thanks for the review. please keep on.

FrancoisYou can look at a much better solution IMHO: Asymptote.

I may confess that it’s not in Python but an amazing solution for 3D with animation and 3D pdf generation have a look at Asymptote:

http://asymptote.sourceforge.net/gallery/

craigPost authorThanks, Anton! I’m glad to hear that you liked it.

Francois–I was actually planning to do a “part 2” of this review covering Asymptote when this site went down due to a server crash. I have hacked together a process to run Asymptote from Python so that I don’t have to manually go through the process of generating a data file and then running Asymptote. I will write a new post on this as soon as I get some time.