5

I came up with the following code to produce a figure in python+matplotlib:

fig = plt.figure(figsize=(10,8)) ax = fig.add_subplot(1,1,1, projection='3d') ax.plot_surface(KX[kxl3d:kxr3d,kxl3d:kxr3d], KY[kxl3d:kxr3d,kxl3d:kxr3d], BLP[kxl3d:kxr3d,kxl3d:kxr3d], rstride=8, cstride=8, alpha=0.4) for idx in range(3): ax.plot(kx[x_points]+momentum_spi[idx,0], ky[y_points]+momentum_spi[idx,1], energy_spi[idx], linestyle='none', marker='o', markerfacecolor=color_spi[idx], markersize=5) ax.set_xlim(kl3d, kr3d) ax.set_ylim(kl3d, kr3d) ax.set_xlabel(r'$k_x[\mu m^{-1}]$') ax.set_ylabel(r'$k_y[\mu m^{-1}]$') ax.set_zlabel(r'$\epsilon-\omega_X[\gamma_p]$') 

The output is: 3d_rings

My question is, how can I

  1. move the z axis label and tick labels to the left hand side of the figure, so that they are not overwritten by the rings and
  2. increase the space between the x and y tick labels and the axes labels (notice they overlap a little, especially for the y axis).
1
  • I think You just set the wrong xlim and ylim. That's why You get unpleasant output. Can You post the complete example? (in the current snippet KX is undefined). Commented Aug 1, 2014 at 10:25

2 Answers 2

7

You can snap zaxis to the left with the code posted here:

tmp_planes = ax.zaxis._PLANES ax.zaxis._PLANES = ( tmp_planes[2], tmp_planes[3], tmp_planes[0], tmp_planes[1], tmp_planes[4], tmp_planes[5]) view_1 = (25, -135) view_2 = (25, -45) init_view = view_2 ax.view_init(*init_view) 

You can control the distance of label to the axis, by adding a new line, and setting linespacing:

ax.set_xlabel('\n' + 'xlabel', linespacing=4) 

Here's a complete example:

#!/usr/bin/python3 import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np X = np.arange(-5, 5, 0.25) Y = np.arange(-5, 5, 0.25) X, Y = np.meshgrid(X, Y) R = np.sqrt(X**2 + Y**2) Z = np.sin(R) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') tmp_planes = ax.zaxis._PLANES ax.zaxis._PLANES = ( tmp_planes[2], tmp_planes[3], tmp_planes[0], tmp_planes[1], tmp_planes[4], tmp_planes[5]) view_1 = (25, -135) view_2 = (25, -45) init_view = view_2 ax.view_init(*init_view) ax.plot_surface(X, Y, Z) ax.set_xlabel('\n' + 'xlabel', linespacing=4) ax.set_ylabel('ylabel') fig.tight_layout() fig.savefig('test.png') 

enter image description here

(Note though that the zx and zy grid goes on the wrong side of the box. I don't know how to fix that).

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

Comments

6

The official way would be to use:

  1. ax.tick_params(axis='z', pad=50)
  2. ax.set_zlabel(r'k_z...', labelpad=30)

However, there is a bit of bad luck. With tick_params the official API documentation for 1.3.1 says: While this function is currently implemented, the core part of the Axes3D object may ignore some of these settings. Seems to be that pad is one of these.

With set_zlabel the documentation says: Currently, labelpad does not have an effect on the labels.

There is a simple workaround for the second one. It is ugly but works:

ax.set_zlabel('\n' + r'$\epsilon-\omega_X[\gamma_p]$', linespacing=2.5) 

You may adjust the position by adjusting the linespacing keyword. The unit is the height of a row of text. (Beware, if you do interactive adjustments, they are not drawn unless you change the text somehow.)

For the z tick labels you could use a similar trick:

ax.set_zticklabels([" "+tl.get_text() for tl in ax.get_zticklabels()]) 

This allows you to adjust the position one space at a time. Of course, in math text mode you may use the spacing commands as well ('\/').

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.