Ошибка отображения matplotlib - узкие полосы и искаженная ось

Я новичок в этом, но мне удалось собрать код, чтобы сделать простую гистограмму из CSV. У меня есть два набора данных, и я могу построить один из них нормально, но при построении другого набора (который является почти идентичным набором данных) он выглядит неправильно. Данные в основном представляют собой два столбца, один со значениями частоты, а другой - с текстом. Текст представляет собой диапазон ячеек для этой частоты и записывается как [10. 20.]. Чтобы построить эти данные, я считываю их как строку и беру первое значение, преобразовывая его в число с плавающей запятой (см. Код), который отлично работает, давая мне два списка значений !!

Затем я беру эти два списка, одну частоту и одну ячейку, и строю их, но в итоге получаются очень узкие полосы (в основном линии) и частота, где значения отображаются как 1e ^ 7 (т.е. 3, а не 30000000), однако ось x отображается нормально.

мой код:

import csv
import numpy as np
import matplotlib.pyplot as plt

inputfile = 'filename'

values = []
bins = []

fh = open(inputfile, 'r+')
for line in fh:
    values.append(float(line.split(',')[0]))
    bins.append(float(line.split(',')[1].replace('[','').replace(']','').strip().split(' ')[0]))

ticks = np.arange(0, 105000, 5000)

plot = plt.bar(bins, values, color='b', alpha=1, width=1)

plt.xlabel('distance (m)')
plt.ylabel('Frequency')
plt.xticks(ticks, rotation=90)
plt.show()

Я бы опубликовал фотографию своего сюжета, но у меня недостаточно очков репутации.

Другие мои данные почти идентичны этим и отлично работают.

Любая помощь приветствуется,

Спасибо


person Nathan Thomas    schedule 23.01.2014    source источник
comment
Вы проверили, содержат ли ячейки и значения ожидаемые числа?   -  person Molly    schedule 23.01.2014


Ответы (1)


Похоже, вы устанавливаете ширину полос на 1, но указываете места, которые очень широко разнесены.

Например, похоже, что вы делаете что-то вроде этого:

import matplotlib.pyplot as plt
import numpy as np
np.random.seed(1977) # Generate same random numbers each time

bins = np.arange(0, 10000, 100)
values = 3e7 * np.random.random(100)

plt.bar(bins, values, width=1)
plt.margins(0.05, 0) % Just for nicer display

plt.show()

введите описание изображения здесь

Проблема в том, что вы указываете width=1. Предположительно, вы бы предпочли, чтобы решетки занимали всю ширину корзины.

Если у вас есть регулярные интервалы, просто укажите их интервал. (например, width = 1000 и т. д.).

Если они расположены нерегулярно, сделайте что-нибудь вроде:

# From looking at your code, "bins" and "values" are the same length.
# Therefore, the width of the last (or first) bar is undefined.
# We'll assume that the width of the last bar is the same as the one before it
diff = np.diff(bins)
widths = np.hstack([diff, diff[-1]])

А затем заговорите с plt.bar(bins, values, width=widths)

введите описание изображения здесь

Наконец, если вы не хотите, чтобы для больших значений использовалась научная нотация, проще всего установить для параметра axes.formatter.limits rc значение большего размера. (По умолчанию все >= 1e7 будет отображаться в экспоненциальной нотации.)

В качестве полного примера:

import matplotlib.pyplot as plt
import numpy as np
np.random.seed(1977)

# Generate data
bins = np.arange(0, 10000, 100)
values = 3e7 * np.random.random(100)

# Don't use scientific notation
plt.rcParams['axes.formatter.limits'] = [-100, 100]

# Plot...
plt.bar(bins, values, width=100)
plt.margins(0.05, 0)
plt.show()

введите описание изображения здесь

person Joe Kington    schedule 23.01.2014
comment
Проблема заключалась в указании ширины, как вы предложили, я принял ее за диапазон от 0 до 1, когда на самом деле мне было нужно 1000. Также plt.rcParams решил мою проблему с осью y. Я бы проголосовал за него, но сначала мне нужно больше очков. Спасибо - person Nathan Thomas; 24.01.2014