【问题标题】:How to customize axes in 3D hist python/matplotlib如何在 3D hist python/matplotlib 中自定义轴
【发布时间】:2014-04-12 00:00:50
【问题描述】:

我正在尝试使用 3D 条形图绘制此数据集

  B    A   freq
  1  2003     2
  1  2003     2
  2  2008     1
  2  2007     2
  2  2007     2
  3  2004     1
  1  2004     3
  1  2004     3
  1  2004     3

我在这里写了代码。

  data = pandas.DataFrame({'A':[2003,2003,2008,2007,2007,2004,2004,2004,2004] , 'B': [1,1,2,2,2,3,1,1,1] ,'C': [2,2,1,2,2,1,3,3,3] })
        fig = plt.figure()
        ax = plt.axes(projection='3d')
        # put 0s on the y-axis, and put the y axis on the z-axis

        #ax.plot(data.A.values, data.B.values,data.freq.values, marker='o', linestyle='--', color="blue", label='ys=0, zdir=z')
        xpos= range(len( data.A.values))
        ypos= range(len( data.B.values))
        zpos= range(len( data.freq.values))

        ax.bar3d(xpos, ypos, zpos, data.A.values, data.B.values,data.freq.values, color='b', alpha=0.5)

        x_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False)
        ax.xaxis.set_major_formatter(x_formatter)

        ax.set_xticks(data.A.values)
        ax.set_yticks(data.B.values)
        ax.set_zticks(data.freq.values)


        plt.savefig("test.png", dpi=300)
        plt.show()

但这似乎不是正确的方法?任何人都可以通过展示我们如何自定义轴来提供帮助吗?

当我使用情节时它会起作用

ax.plot(data.A.values, data.B.values,data.freq.values,marker='o', linestyle='--', color='r')

而不是 bar3D

ax.bar3d(xpos, ypos, zpos, data.A.values, data.B.values,data.freq.values, color='b', alpha=0.5)

但我想使用 3D 直方图更好地理解。

【问题讨论】:

    标签: python matplotlib pandas


    【解决方案1】:

    您似乎误解了 bar3d 函数的参数:

    bar3d(x, y, z, dx, dy, dz)

    • 参数xyz分别是横条在x、y、z轴上的坐标。
    • 参数dxdydz分别是x、y和z轴上的条的大小。

    例如,如果要绘制以下数据集:

    {'A': [1, 2], 'B': [2003, 2008] ,'freq': [2, 3] }

    你必须像这样定义这些参数:

    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    
    xpos = [1, 2]
    ypos = [2003, 2008]
    zpos = [0, 0]
    
    dx = 1
    dy = 1
    dz = [2, 3]
    
    fig = plt.figure()
    ax = plt.axes(projection='3d')
    ax.bar3d(xpos, ypos, zpos, dx, dy, dz)
    plt.show()
    

    这是:

    • 您在 (1, 2003, 0) (x, y, z) 中绘制一个高度为 2 的条形。
    • 您在 (2, 2008, 0) (x, y, z) 中绘制一个高度为 3 的条形。
    • 两个条形在 x 和 y 轴上的大小均为 1,但可能会更小,这只是美学问题。

    上面的脚本生成如下图:

    如果您查看图片,您会发现一些小的格式问题:

    • 年份以指数形式表示。
    • 条形图不在其 (x, y) 坐标上居中。

    我们实际上可以通过一些调整来解决这个问题:

    import matplotlib
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    
    xpos = [1, 2]
    ypos = [2003, 2008]
    zpos = [0, 0]
    
    dx = 1
    dy = 1
    dz = [2, 3]
    
    # Move each (x, y) coordinate to center it on the tick
    
    xpos = map(lambda x: x - 0.5, xpos)
    ypos = map(lambda y: y - 0.5, ypos)
    
    fig = plt.figure()
    ax = plt.axes(projection='3d')
    ax.bar3d(xpos, ypos, zpos, dx, dy, dz)
    
    # Do not print years in exponential notation
    
    y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False)
    ax.yaxis.set_major_formatter(y_formatter)
    
    plt.show()
    

    最后我们会得到:

    【讨论】:

      【解决方案2】:

      你错的地方太多了,所以我只是发布它应该是什么样的:

      import matplotlib.pyplot as plt
      from mpl_toolkits.mplot3d import Axes3D
      
      data = pd.DataFrame({'A': [1,1,2,2,2,3,1,1,1], 'B': [2003,2003,2008,2007,2007,2004,2004,2004,2004] ,'freq': [2,2,1,2,2,1,3,3,3] })
      fig = plt.figure()
      ax = fig.add_subplot(111, projection='3d')
      # put 0s on the y-axis, and put the y axis on the z-axis
      
      #ax.plot(data.A.values, data.B.values,data.freq.values, marker='o', linestyle='--', color="blue", label='ys=0, zdir=z')
      PV = pd.pivot_table(data, values='freq',rows='A',cols='B')
      xpos=np.arange(PV.shape[0])
      ypos=np.arange(PV.shape[1])
      xpos, ypos = np.meshgrid(xpos+0.25, ypos+0.25)
      xpos = xpos.flatten()
      ypos = ypos.flatten()
      zpos=np.zeros(PV.shape).flatten()
      dx=0.5 * np.ones_like(zpos)
      dy=0.5 * np.ones_like(zpos)
      dz=PV.values.ravel()
      dz[np.isnan(dz)]=0.
      
      ax.bar3d(xpos,ypos,zpos,dx,dy,dz,color='b', alpha=0.5)
      ax.set_xticks([.5,1.5,2.5])
      ax.set_yticks([.5,1.5,2.5,3.5])
      ax.w_yaxis.set_ticklabels(PV.columns)
      ax.w_xaxis.set_ticklabels(PV.index)
      ax.set_xlabel('A')
      ax.set_ylabel('B')
      ax.set_zlabel('Occurrence')
      
      plt.savefig("test.png", dpi=300)
      plt.show()
      

      【讨论】:

      • 您能否说明一下如何调整轴。让我们 = data= pandas.DataFrame({'A': np.random.rand(100)*1000 , 'B':np.random.rand(100)*10 ,'freq':np.random.rand(100 )*2220 }) 。我应该更改 ax.set_xticks 还是 w_yaxis.set_ticklabels ,这有点令人困惑
      • 是的,我认为您需要,但您首先需要从DataFrame data 中创建一个pivot_table,您的ticksticklabels 将根据data 的数据透视表。
      猜你喜欢
      • 2016-05-21
      • 1970-01-01
      • 2020-04-21
      • 1970-01-01
      • 1970-01-01
      • 2021-05-26
      • 2018-12-01
      • 2012-02-04
      • 1970-01-01
      相关资源
      最近更新 更多