2

I'm trying to a 3d figure without any plot elements in python. Sort of a 3d version of this.

When I run the code I have added below, I get regular plota figure of (Very) simplified surface. I want to remove the axes, axes labels, ticks, and background (and remain only with the surface).

How can I remove them.

Also, is there way to add arrows to the plot?

Here is my code:

import random
import math

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

pi = 3.14159
bignum = 3
amp = 0.1

mat = []
X = []
Y = []
class mode:
    i=0
    j=0
    phase=0
    amp=0
modes = dict() 
for i in range(0,3):
    submodes = dict()
    for j in range (0,5):
        if not (i==0 and j==2):
            m = mode()
            m.i = i
            m.j = j
            m.amp = amp*random.random()/(pow(i,2) + pow(j-2,2))
            m.phase = random.random()*2*pi
            submodes[j] = m
            modes[i] = submodes

for x in range (0,bignum): 
    mat.append([])
    for y in range (0,bignum):
        dz = 0
        for i in range (0,3):
            for j in range (0,5):
                if not (i == 0 and j == 2):
                    dz += math.cos(i*x*2*pi/bignum + j *y*2/bignum + modes[i][j].phase)*modes[i][j].amp
        mat[x].append(dz)

X = np.mgrid[:bignum,:bignum]
print (len(X[0]))
print (len(mat))
fig = plt.figure(figsize=plt.figaspect(2.))
fig.frameon=True

ax = fig.add_subplot(1,1,1, projection='3d')
ax.frameon=False
ax.xticks=[]
ax.yticks=[]
ax.zticks=[]
surf = ax.plot_surface(X[0],X[1],mat,rstride=1, cstride=1,
        linewidth=0, antialiased=False)
ax.set_zlim3d(0, 1)
plt.show()
1
  • Not that this is off topic here (because it isn't), but this kind of question would also fit on Computational Science, and it'd benefit from an audience more dedicated to scientific computation. Commented Jan 12, 2012 at 23:53

2 Answers 2

1

To eliminate the 3d frame from the figure, use:

ax.set_axis_off()

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

add this and you get a totally gray background plt.setp(ax.get_frame(), visible = False). At the very least you should use ndarrays instead of dict, vectorization takes time to learn for sure but can save you on large data sets
1

This doesn't answer much of your question. But you can start turning stuff off with

plt.setp(ax.get_xticklabels(), visible=False)

I did some of it below. Also, the plt.annotate() function is how to add arrows in 2d plots...not sure how it upscales.

import random
import math

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

pi = 3.14159
bignum = 3
amp = 0.1

mat = []
X = []
Y = []
class mode:
    i=0
    j=0
    phase=0
    amp=0
modes = dict() 
for i in range(0,3):
    submodes = dict()
    for j in range (0,5):
        if not (i==0 and j==2):
            m = mode()
            m.i = i
            m.j = j
            m.amp = amp*random.random()/(pow(i,2) + pow(j-2,2))
            m.phase = random.random()*2*pi
            submodes[j] = m
            modes[i] = submodes

for x in range (0,bignum): 
    mat.append([])
    for y in range (0,bignum):
        dz = 0
        for i in range (0,3):
            for j in range (0,5):
                if not (i == 0 and j == 2):
                    dz += math.cos(i*x*2*pi/bignum + j *y*2/bignum + modes[i][j].phase)*modes[i][j].amp
        mat[x].append(dz)

X = np.mgrid[:bignum,:bignum]
print (len(X[0]))
print (len(mat))
fig = plt.figure(figsize=plt.figaspect(2.))
fig.frameon=True

ax = fig.add_subplot(1,1,1, projection='3d')
ax.frameon=False

surf = ax.plot_surface(X[0],X[1],mat,rstride=1, cstride=1,
        linewidth=0, antialiased=False)
ax.set_zlim3d(0, 1)
plt.setp(ax.get_xticklabels(), visible=False)
plt.setp(ax.get_yticklabels(), visible=False)
plt.setp(ax.get_zticklabels(), visible=False)
plt.setp(ax.get_xticklines(), visible=False)
plt.setp(ax.get_yticklines(), visible=False)
plt.setp(ax.get_zticklines(), visible=False)
plt.setp(ax.get_frame(), visible = False)
#plt.annotate(r'Hello', xy = (.5, .5),
#                xytext = (10,10),
#                textcoords='offset points', arrowprops=dict(arrowstyle='->',
#                                                connectionstyle='arc3,rad=0'))

plt.show()

You didn't ask this...but you should vectorize this code. Most/(all?) of the for loops could be avoided.

1 Comment

Thanks. I know I should avoid loops but I can't see how I can escape them here. Mainly the power of i and j.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.