【问题标题】:How to plot in 3D with a double entry table - Matplotlib如何使用复式表在 3D 中绘图 - Matplotlib
【发布时间】:2018-05-25 00:32:16
【问题描述】:

我想用 Pandas / MatplotLib(线框或其他,我不在乎)进行 3D 绘图,但以特定方式..

我正在使用 RFID 传感器,我正在尝试记录我在不同距离 + 不同角度接收到的信号。我想看看距离的上升和角度的相关性。

这就是我想用 3D 绘图的原因:

X 轴 -> 距离,Y 轴 -> 角度,Z 轴 -> 接收到的信号,表示浮点数

我生成 DataFrame 的 CSV 文件的组织方式如下:

Distance;0;23;45;90;120;180
0;-53.145;-53.08;-53.1;-53.035;-53.035;-53.035
5;-53.145;-53.145;-53.05;-53.145;-53.145;-53.145
15;-53.145;-53.145;-53.145;-53.145;-53.145;-53.145
25;-53.145;-52.145;-53.145;-53.002;-53.145;-53.145
40;-53.145;-53.002;-51.145;-53.145;-54.255;-53.145
60;-53.145;-53.145;-53.145;-53.145;-53.145;-53.145
80;-53.145;-53.145;-53.145;-53.145;-60;-53.145
100;-53.145;-52;-53.145;-54;-53.145;-53.145
120;-53.145;-53.145;-53.145;-53.145;-53.002;-53.145
140;-51.754;-53.145;-51.845;-53.145;-53.145;-53.145
160;-53.145;-53.145;-49;-53.145;-53.145;-53.145
180;-53.145;-53.145;-53.145;-53.145;-53.145;-53.002
200;-53.145;-53.145;-53.145;-53.145;-53.145;-53.145

在第一行标签上,我们有不同的角度:0°、23°、45°、... 而DataFrame的索引是距​​离:0 cm, 15 cm...

而里面的矩阵代表的是信号,所以,Z轴的值...

但我不知道如何生成 3D Scatter、WireFrame...因为在每个教程中我都看到有人使用特定的列作为轴。

确实,在我的 CSV 文件的第一行中,我有所有列的标签

Distance;0  ;23 ;45 ;90 ;120;180

而且我不知道如何使用复式表生成 3D 图。

你知道怎么做吗?或者,以更好的方式生成我的 CSV 文件以在最后看到相同的结果!

如果你能帮我解决这个问题,我将不胜感激!

谢谢!

【问题讨论】:

  • 嗯,您的 z 值始终为 -45。您是否有更多数据或不同的子集可以共享?
  • 这些数据仅供参考。实际上,数据应该在 -20 到 -70 之间

标签: python pandas matplotlib


【解决方案1】:

也许contour就够了

b = np.array([0,5,15,25,40,60,80,100,120,140,160,180,200])
a = np.array([0,23,45,90,120,180])
x, y = np.meshgrid(a, b)
z = np.random.randint(-50,-40, (x.shape))

scm = plt.contourf(x, y, z, cmap='inferno')
plt.colorbar(scm)
plt.xticks(a)
plt.yticks(b)
plt.xlabel('Distance')
plt.ylabel('Angle')
plt.show()

展示

【讨论】:

    【解决方案2】:

    你可以得到一个类似这样的等高线图(但是对于显示的数据,它不是很有趣,因为所有的值都是恒定的 -45):

    df = pd.read_csv(sep=';')
    df = df.set_index('Distance')
    x = df.index
    y = df.columns.astype(int)
    z = df.values
    X,Y = np.meshgrid(x,y)
    Z = z.T
    plt.contourf(X,Y,Z,cmap='jet')
    plt.colorbar()
    plt.show()
    

    【讨论】:

      【解决方案3】:

      欢迎来到stackoverflow,您的问题可以分为几个步骤:

      第 1 步 - 读取数据

      我已将您的数据存储在名为data.txt 的文件中。

      我不太了解 Pandas,但是这也可以通过 Numpy 的简单函数 loadtxt 来处理。由于第一列和第一行中的文本“距离”值,您的数据有点问题。但不要惊慌,我们将文件加载为字符串矩阵:

      raw_data = np.loadtxt('data.txt', delimiter=';', dtype=np.string_)
      

      第 2 步 - 转换原始数据

      要从原始数据中提取想要的数据,我们可以执行以下操作:

      angle    = raw_data[0 , 1:].astype(float)
      distance = raw_data[1:, 0 ].astype(float)
      data     = raw_data[1:, 1:].astype(float)
      

      使用indexing 原始数据我们选择我们想要的数据,使用astype 我们将字符串值更改为数字。

      中间步骤 - 使数据更花哨

      你的数据有点无聊,只有-45的值,我冒昧地把它弄得更花哨了:

      data = (50 + angle[np.newaxis,:]) / (10 + np.sqrt(distance[:,np.newaxis])) 
      

      第 4 步 - 制作线框图

      matplotlib.org 的示例看起来很简单:

      fig = plt.figure()
      ax = fig.add_subplot(111, projection='3d')
      ax.plot_wireframe(X, Y, Z)
      plt.show()
      

      但诀窍是正确设置X, Y, Z 参数...

      第 3 步 - 制作 XY 数据

      Z 数据就是我们的 data 值:

      Z = data
      

      XY 也应该是二维数组,这样plot_wireframe 可以在二维数组 XY 的相同数组位置找到 Z 的每个值的 x 和 y .有一个 Numpy 函数可以创建这些二维数组:

      X, Y = np.meshgrid(angle, distance)
      

      第 5 步 - 稍微调整一下

      ax.set_xticks(angle)
      ax.set_yticks(distance[::2])
      ax.set_xlabel('angle')
      ax.set_ylabel('distance')
      

      把它放在一起

      所有步骤都按正确的顺序排列在一起:

      # necessary includes...
      from mpl_toolkits.mplot3d import axes3d
      import matplotlib.pyplot as plt
      import numpy as np
      
      raw_data = np.loadtxt('data.txt', delimiter=';', dtype=np.string_)
      
      angle    = raw_data[0 , 1:].astype(float)
      distance = raw_data[1:, 0 ].astype(float)
      data     = raw_data[1:, 1:].astype(float)
      
      
      # make the example data a bit more interesting...
      data = (50 + angle[np.newaxis,:]) / (10 + np.sqrt(distance[:,np.newaxis])) 
      
      # setting up the plot
      fig = plt.figure()
      ax = fig.add_subplot(111, projection='3d')
      
      # the trickey part creating the data that plot_wireframe wants
      Z = data
      X, Y = np.meshgrid(angle, distance)
      
      ax.plot_wireframe(X, Y, Z)
      
      # fancing it up a bit
      ax.set_xticks(angle)
      ax.set_yticks(distance[::2])
      ax.set_xlabel('angle')
      ax.set_ylabel('distance')
      
      # and showing the plot ...
      plt.show()
      

      【讨论】:

      • Niceee 完美运行!我的意思是检查一下(数据中有特定值)imgur.com/a/7H5IFkT... 但是你知道如何在“弹出”窗口中绘图吗?我的意思是,如果我能知道的话会更好,将摄像机从另一个视图移动到 Wireframe ! (顺便说一句!)
      • 我现在有完美的数据,但我不知道如何使用这一行数据来访问它们 data = (50 + angle[np.newaxis,:]) / (10 + np.sqrt(距离[:,np.newaxis]))。我想将我的数据放入数组中
      猜你喜欢
      • 1970-01-01
      • 2021-03-08
      • 2019-10-18
      • 2014-10-06
      • 1970-01-01
      • 2016-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多