Как построить в 3D с таблицей двойной записи - Matplotlib - PullRequest
0 голосов
/ 18 мая 2018

Я хотел бы построить в 3D с помощью Pandas / MatplotLib (каркас или другое, мне все равно), но определенным образом.

Я использую RFID-датчики и пытаюсь записатьсигнал я получаю на разном расстоянии + под разными углами.И я хочу увидеть корреляцию между увеличением расстояния и углом.

Так вот почему я хочу построить в 3D:

Ось X -> Расстояние, Ось Y ->Угол, Ось Z -> полученный сигнал, который означает число с плавающей запятой

Мой CSV-файл, из которого я генерирую свой DataFrame, организован следующим образом: таблица с двойной записью:

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 см, 15 см ...

И матрица внутри представляетсигнализируют о значениях оси Z ...

Но я не знаю, как сгенерировать 3D Scatter, WireFrame ... потому что в каждом уроке я вижу людей, которые используют определенные столбцы в качестве оси.

Действительно, в моем CSV-файле в первой строке есть метка всех столбцов

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

И я не знаю, как сгенерировать трехмерный график с таблицей двойной записи.

Ты знаешь, как это сделать?Или, чтобы лучше создать мой CSV-файл, чтобы увидеть тот же результат в конце!

Буду признателен, если вы поможете мне с этим!

Спасибо!

Ответы [ 3 ]

0 голосов
/ 18 мая 2018

Вы можете получить контурный график с чем-то вроде этого (но для показанных данных это не очень интересно, так как все значения постоянны при -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()
0 голосов
/ 18 мая 2018

Добро пожаловать в stackoverflow, ваш вопрос можно разделить на несколько этапов:

Шаг 1 - чтение данных

Я сохранил ваши данные в файле с именем data.txt.

Я не очень хорошо знаю Панд, но это также можно сделать с помощью простой функции 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)

При индексации необработанных данных мы выбираем нужные данные, а при 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 - сделать данные X и Y

Данные Z - это просто наши data значения:

Z = data

X и Y также должны быть двумерными массивами, так что plot_wireframe может найти x и y для каждого значения 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()
0 голосов
/ 18 мая 2018

возможно 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()

отображает

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...