问题描述
我正在使用Python中的Matplotlib进行一些3D表面绘图,并且注意到了一个令人讨厌的现象.根据我设置视点(相机位置)的方式,垂直(z)轴在左侧和右侧之间移动.这是两个示例:示例1,轴左,示例2,轴右.第一个示例具有ax.view_init(25,-135),第二个示例具有ax.view_init(25,-45).
I'm doing some 3D surface plots using Matplotlib in Python and have noticed an annoying phenomenon. Depending on how I set the viewpoint (camera location), the vertical (z) axis moves between the left and right side. Here are two examples: Example 1, Axis left, Example 2, Axis right. The first example has ax.view_init(25,-135) while the second has ax.view_init(25,-45).
我想保持观点相同(查看数据的最佳方法).有什么方法可以将轴推向一侧或另一侧?
I would like to keep the viewpoints the same (best way to view the data). Is there any way to force the axis to one side or the other?
推荐答案
我需要类似的东西:在两侧绘制zaxis.感谢@crayzeewulf的回答,我来到了以下解决方法(左侧,右侧或两侧):
I needed something similar: drawing the zaxis on both sides. Thanks to the answer by @crayzeewulf I came to following workaround (for left, righ, or both sides):
首先根据需要绘制3d,然后在调用show()
之前,将Wcapper类包装在Axes3D
中,该类将简单地覆盖draw()
方法.
First plot your 3d as you need, then before you call show()
wrap the Axes3D
with a Wrapper class that simply overrides the draw()
method.
Wrapper类调用仅将某些功能的可见性设置为False,它会绘制自身,并最终使用修改后的PLANES绘制z轴.该包装程序类使您可以在左侧,向右或在两侧绘制zaxis.
The Wrapper Class calls simply sets the visibility of some features to False, it draws itself and finally draws the zaxis with modified PLANES. This Wrapper Class allows you to draw the zaxis on the left, on the rigth or on both sides.
import matplotlib
matplotlib.use('QT4Agg')
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
class MyAxes3D(axes3d.Axes3D):
def __init__(self, baseObject, sides_to_draw):
self.__class__ = type(baseObject.__class__.__name__,
(self.__class__, baseObject.__class__),
{})
self.__dict__ = baseObject.__dict__
self.sides_to_draw = list(sides_to_draw)
self.mouse_init()
def set_some_features_visibility(self, visible):
for t in self.w_zaxis.get_ticklines() + self.w_zaxis.get_ticklabels():
t.set_visible(visible)
self.w_zaxis.line.set_visible(visible)
self.w_zaxis.pane.set_visible(visible)
self.w_zaxis.label.set_visible(visible)
def draw(self, renderer):
# set visibility of some features False
self.set_some_features_visibility(False)
# draw the axes
super(MyAxes3D, self).draw(renderer)
# set visibility of some features True.
# This could be adapted to set your features to desired visibility,
# e.g. storing the previous values and restoring the values
self.set_some_features_visibility(True)
zaxis = self.zaxis
draw_grid_old = zaxis.axes._draw_grid
# disable draw grid
zaxis.axes._draw_grid = False
tmp_planes = zaxis._PLANES
if 'l' in self.sides_to_draw :
# draw zaxis on the left side
zaxis._PLANES = (tmp_planes[2], tmp_planes[3],
tmp_planes[0], tmp_planes[1],
tmp_planes[4], tmp_planes[5])
zaxis.draw(renderer)
if 'r' in self.sides_to_draw :
# draw zaxis on the right side
zaxis._PLANES = (tmp_planes[3], tmp_planes[2],
tmp_planes[1], tmp_planes[0],
tmp_planes[4], tmp_planes[5])
zaxis.draw(renderer)
zaxis._PLANES = tmp_planes
# disable draw grid
zaxis.axes._draw_grid = draw_grid_old
def example_surface(ax):
""" draw an example surface. code borrowed from http://matplotlib.org/examples/mplot3d/surface3d_demo.html """
from matplotlib import cm
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)
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)
if __name__ == '__main__':
fig = plt.figure(figsize=(15, 5))
ax = fig.add_subplot(131, projection='3d')
ax.set_title('z-axis left side')
ax = fig.add_axes(MyAxes3D(ax, 'l'))
example_surface(ax) # draw an example surface
ax = fig.add_subplot(132, projection='3d')
ax.set_title('z-axis both sides')
ax = fig.add_axes(MyAxes3D(ax, 'lr'))
example_surface(ax) # draw an example surface
ax = fig.add_subplot(133, projection='3d')
ax.set_title('z-axis right side')
ax = fig.add_axes(MyAxes3D(ax, 'r'))
example_surface(ax) # draw an example surface
plt.show()
这篇关于更改3D图(Matplotlib)的垂直(z)轴的位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!