Python Matplotlib создает коробочный график из данных в мВт, график в дБм - PullRequest
0 голосов
/ 17 января 2020

У меня есть набор данных, который содержит значение RSSI в мВт и метку устройства. См. Пример данных ниже.

Моя цель - создать коробку среднего RSSI, сгруппированную по метке устройства, но я бы хотел, чтобы она печаталась в логарифмическом масштабе c дБм, а не в линейном масштабе мВт.

У меня есть функция для преобразования:

def toDeciBellMilliWatt(RSSI):
    """Returns RSSI value in dBm, assuming input is mW"""
    return 10*math.log10(RSSI)

И этот вызов может создать boxplots (обратите внимание, я после них, потому что box и усы отображают квантили Мне не нужны графики) Мне нужно:

data.boxplot(column='RSSI', by='label')

но я бы хотел, чтобы ось y была в дБм. Есть ли способ достичь этого сразу после того, как вызов boxplot вычислил все квантили? Не знаю, с чего начать

пример данных:

data = pd.DataFrame(columns=['label', 'RSSI'],
                    data=[['A', 1.99e-7],
                          ['B', 1.25e-9],
                          ['A', 1.99e-5],
                          ['A', 3.16e-7],
                          ['B', 3.16e-5],
                          ['A', 1.99e-7],
                          ['B', 3.91e-9],
                          ['A', 1.99e-5],
                          ['A', 3.14e-7],
                          ['B', 3.16e-5]])

изменить , чтобы избежать путаницы: среднее значение в мВт, преобразованное в дБм, не равно к средним значениям дБм. Это довольно легко продемонстрировать на бумаге и связано с тем, что дБм является логарифмическим масштабом, а мВт - нет.

При вычислении значений statisti c с помощью Boxplot в мВт мы получаем " правильная «средняя мощность сигнала». Теперь мне не хватает фрагмента, чтобы показать его в дБм, чтобы технические люди могли его понять.

Я мог бы самостоятельно вычислить все значения, а затем собрать блок-график из моих расчетов. То, что мне нужно, - это решение преобразовать единицу измерения оси Y всего боксплота, созданного Matplotlib, в логарифмический масштаб.

1 Ответ

1 голос
/ 18 января 2020

Один из подходов состоит в том, чтобы сначала нарисовать блокпост с помощью pandas, затем установить ось y на логарифмическое значение c и изменить форматирование тиков. Вы можете удалить второстепенные тики, так как они путают с новыми метками тиков.

import math
import pandas as pd
from matplotlib import pyplot as plt

def toDeciBellMilliWatt(RSSI):
    """Returns RSSI value in dBm, assuming input is mW"""
    return 10 * math.log10(RSSI)

def format_dBm(value, tick_number):
    return '–' + str(round(-toDeciBellMilliWatt(value)))

data = pd.DataFrame(columns=['label', 'RSSI'],
                    data=[['A', 1.99e-7],
                          ['B', 1.25e-9],
                          ['A', 1.99e-5],
                          ['A', 3.16e-7],
                          ['B', 3.16e-5],
                          ['A', 1.99e-7],
                          ['B', 3.91e-9],
                          ['A', 1.99e-5],
                          ['A', 3.14e-7],
                          ['B', 3.16e-5]])
fig, axes = plt.subplots(ncols=2, figsize=(10, 4))
for ax in axes:
    data.boxplot(column='RSSI', by='label', ax=ax)
plt.subplots_adjust(wspace=0.25)
plt.yscale('log')
plt.minorticks_off()
axes[1].yaxis.set_major_formatter(plt.FuncFormatter(format_dBm))
plt.ylabel('RSSI (in dBm)')
plt.show()

Слева оригинальное поле, в центре с метками y-tick в дБм, справа версия с логарифмическими c галочками. Из-за этого масштабирования боксплот меняет свой визуальный аспект.

example plot

...