Я пытаюсь создать график и использую журнал для отображения относительного сравнения, график отображается правильно, однако на сохраненном рисунке нет никаких графиков, только ось.
import matplotlib.pyplot as plt
# Data
y_values = [4.385236951214598, 4.385249349505862, 4.38524255048674, 4.385237751115038, 4.385241350648787]
x_labels = ["Dota", "Youtube", "Exchange", "Fifa", "Uber"]
# Create the plot
fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(x_labels, y_values, color=plt.cm.viridis(range(len(x_labels))))
# Set y-axis to log scale
ax.set_yscale('log')
# Add title and labels
ax.set_title("Contracts vs. Values (Log Scale)")
ax.set_xlabel("Contracts")
ax.set_ylabel("Values")
# Save the plot as a PDF file
fig.savefig('gas-burnt-per-contract.pdf', dpi=300, bbox_inches='tight', transparent=True, pad_inches=0)
# Display the plot
plt.show()
Виновная строка — ax.set_yscale('log')
. Если я удалю ее, график будет отображаться правильно на сохраненном рисунке, но будет пустым, когда я его использую.
Любая помощь будет оценена по достоинству.
Я запустил код OP как есть, как сценарий в VScode, и могу подтвердить совпадения поведения, которые я наблюдаю, с сообщениями OP.
Смотрите этот ответ: stackoverflow.com/questions/31193976/…
При дальнейшем тестировании сохраненный PDF-файл соответствует показанному изображению, если тип графика изменен на точечный, а не на полосчатый.
@BillHorvath: использование plt.yscale("log")
вместо ax.set_yscale("log")
не изменило проблемное поведение - разве я неправильно понял рекомендацию в ответе, на который вы ссылаетесь?
При (еще) дальнейшем тестировании ничего не меняя, кроме формата сохраненного рисунка с PDF на PNG, достигается желаемое поведение. Казалось бы, проблема заключается в использовании PDF в качестве целевого формата. Похоже, это может быть ошибка.
SVG (векторный) работает так же, как PNG (растровый), поэтому проблема, похоже, не в нем.
Я считаю, что вы обнаружили ошибку matplotlib
.
Возможно, ошибка локализована в методе savefig
. Вот что я пробовал:
Код как есть
Запустив ваш код как есть, я получаю именно то поведение, которое вы описываете. Следующее изображение show
n...
НО, как вы сообщаете, в сохраненном PDF-файле нет полос внутри осей:
Использование plt.yscale()
вместо ax.set_yscale()
Использование plt.yscale()
(как предложено в этом ответе вместо ax.set_yscale()
, как вы это сделали, не имеет никакого значения.
Изменение входных значений
Если я изменю y_values с:
y_values = [
4.385236951214598,
4.385249349505862,
4.38524255048674,
4.385237751115038,
4.385241350648787,
к...
y_values = [
4.385236951214598,
5.385249349505862,
6.38524255048674,
7.385237751115038,
8.385241350648787,
И PDF, и «показанное» изображение идеально совпадают:
Если я изменю только одно из чисел, добавив к нему 1, я все равно получу совпадающие и действительные изображения:
То же самое произойдет, если я прибавлю 0,01 к одному из чисел, но если я уменьшу прибавку всего до 0,001, результаты снова станут неверными.
Используя decimal.Decimal()
Я попробовал преобразовать все y_values
в Decimal
, но это не имело никакого значения.
Проверка наличия проблем с SVG, как и с PDF
Тот факт, что в формате PNG используется растр, а не вектор, как в PDF, заставил меня задуматься, а не вектор ли это или растр.
Но сохранение в SVG работает отлично, отображаемые и сохраненные изображения совпадают.
Поскольку SVG — это векторные файлы, такие же, как PDF-файлы, это наводит меня на мысль, что это все-таки не векторная/растровая вещь.
Настройка transparent=False
Установка transparent
кварга на False
в fig.savefig()
не имеет никакого значения.
Увеличение или уменьшение dpi
Увеличение или уменьшение dpi при вызове fig.savefig()
не имеет значения.
Изменение размера фигуры
Увеличение/уменьшение фигуры и изменение ее соотношения сторон не имеют значения.
Изменение цвета полосы
Изменение цветов, вызываемых при вызове ax.bar()
, не имеет значения.
Заключение
Это очень непоследовательное поведение заставляет меня думать, что это какая-то matplotlib
ошибка.
Тот факт, что проблема возникает только тогда, когда разница между значениями уменьшается примерно до 0,001, заставляет меня думать, что это может быть связано с округлением, но я не уверен...
Моя установка
Я запускаю ваш код в VSCode, используя Python 3.11, matplotlib v3.9.0, в Windows 10.
Сохраняемый график аналогичен тому, что отображается в блокноте Jupyter, если код запускается как есть.