如何在同一图表上获得两个表面图的独立缩放

时间:2015-01-09 15:26:58

标签: python matplotlib plot charts

我试图在同一组3d轴上绘制两个数据值。两个数据集的值可以相差1或2个数量级。因此,我希望两个Z轴类似于2d图的twinx或twiny命令。下面的代码中显示了一个粗略的例子

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


result=[['1', '2', '3'],
['4', '5', '6'],
['7', '8', '9']]

result = np.array(result, dtype=np.int)

fig=plt.figure(figsize=(5, 5), dpi=150)
ax1=fig.add_subplot(111, projection='3d')

xlabels = np.array(['data1x', 'data2x', 'data3x'])
xpos = np.arange(xlabels.shape[0])
ylabels = np.array(['data1y','data2y','data3y'])
ypos = np.arange(ylabels.shape[0])

xposM, yposM = np.meshgrid(xpos, ypos, copy=False)

zpos=result
zpos = zpos.ravel()

dx=0.5
dy=0.5
dz=zpos

ax1.w_xaxis.set_ticks(xpos + dx/2.)
#ax1.w_xaxis.set_ticklabels(xlabels)

ax1.w_yaxis.set_ticks(ypos + dy/2.)
#ax1.w_yaxis.set_ticklabels(ylabels)

values = np.linspace(0.2, 1., xposM.ravel().shape[0])
colors = cm.rainbow(values)
ax1.bar3d(xposM.ravel(), yposM.ravel(), dz*0, dx, dy, dz, color=colors)
X = np.arange(-1, 1, 0.25)
Y = np.arange(-1, 1, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = 100*np.sin(R)
surf = ax1.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm,
    linewidth=0, antialiased=False)
plt.show()

如何更改其中一个图的z比例,以便更好地查看两者的特征?

2 个答案:

答案 0 :(得分:1)

您可以缩放其中一个数组的数据,以对应另一个数组的数量。然后,在绘制时,z - 延伸将具有可比性 为了包含显示原始数据范围的缩放数据的颜色条,我使用了第二组轴。

  1. 导入以下附加库:

    import matplotlib as mpl # for general access to the colorbar class
    import matplotlib.gridspec as gridspec # to set up an axis-grid  
    
  2. 设置轴:

    gs = gridspec.GridSpec(1, 2,
                   width_ratios=[20,1],
                   )
    
    ax1 = fig.add_subplot(gs[0], projection='3d')
    ax2 = fig.add_subplot(gs[1])  
    

    您可以调整宽度比以相对于数据图(由ax2给出)更改颜色条的宽度(由ax1给出)。

  3. 使用numpy的amax来确定缩放的两个数据集的最大值(在调用曲面图时可以注意这一点:

    surf = ax1.plot_surface(X, Y, Z/np.amax(Z)*np.amax(zpos), 
                            rstride=1, cstride=1, cmap=cm.coolwarm, 
                            linewidth=0, antialiased=False)
    

    使用Z/np.amax(Z)*np.amax(zpos)会将您的Z - 数据缩放到zpos的幅度。

  4. 现在,在第二个轴上绘制一个颜色条:

    cbar = mpl.colorbar.ColorbarBase(ax2, cmap = cm.coolwarm, 
               norm=mpl.colors.Normalize(vmin=np.amin(Z), vmax=np.amax(Z)))
    

    要确保颜色栏涵盖Z - 日期的范围,请使用norm功能。

  5. 这是你的情节:

    scaled data, unscaled colorbar

答案 1 :(得分:1)

您可以在第一个轴上放置第二个 - 透明轴,并使用共享的xy轴。

  1. 设置第二组轴,包括sharex and sharey

    ax2 = fig.add_axes(ax1.get_position(), projection='3d', 
                       sharex=ax1, sharey=ax1)
    
  2. 使背景透明并删除实际的轴线(和刻度线等):

    ax2.set_axis_off()
    ax2.patch.set_facecolor('none')
    
  3. 如前所述绘图,但指定第二个轴(ax2),您也可以不加任何额外的努力绘制颜色条:

    surf = ax2.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm,
                            linewidth=0, antialiased=False)
    
    cb = fig.colorbar(surf,ax=ax1)
    
  4. 设置xlimylim以避免任何错位(这可能与数据相关联):

    ax1.set_xlim([-1.0, 3.0])
    ax1.set_ylim([-1.0, 3.0])
    
  5. 结果图将是:

    axis overlay