Цветной логарифмический график: удаление степени 10 маркировки

Я немного искал, уже столкнулся со следующими связанными вопросами: Matplotlib: отключите степени десяти в логарифмическом графике

Предотвратить попадание осей в научный нотация (степень 10) с использованием matplotlib в Python на полулогическом графике

Однако ни один из них не смог реально помочь мне. По сути, я делаю достаточно простую диаграмму рассеяния с соответствующей картой цветов, однако я не могу избавиться от маркировки мощности 10 на оси Y. Вот мой код и получившийся сюжет. 'teff', 'lum' и 'col1' — это серии dtype('float64'), и я определил цветовую карту rvb в отдельной функции.

plt.figure(figsize=(12,6))
plt.scatter(teff,lum,s=10,c=col1, cmap=rvb)
plt.yscale('log')
plt.colorbar()
axes = plt.gca()
plt.gca().invert_xaxis()
plt.xlabel('Effective Temperature [K]')
plt.ylabel('Luminosity [L$_{\odot}$]')
plt.show()

Текущая диаграмма рассеяния

Я пробовал несколько вариантов следующего решения, найденного в похожих вопросах.

from matplotlib.ticker import ScalarFormatter
ax.get_yaxis().get_major_formatter().set_useOffset(False)

Однако я просто получаю ошибки, например. Объект LogFormatterSciNotation не имеет атрибута set_useOffset.

Я также пытался решить проблему с помощью подзаговоров, но тогда я не могу заставить работать цветовую карту. Я надеюсь на решение, которое позволит мне сохранить мой график почти идентичным, просто с изменением степени 10 на фактические числа и, если возможно, с более регулярными интервалами.

Спасибо!


person qwerty    schedule 30.07.2019    source источник


Ответы (2)


Вот рабочая версия, в которой используются объекты осей:

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

from matplotlib.ticker import ScalarFormatter

x = [i for i in range(10)]
y = [i for i in range(10)]
z =  [i for i in range(20,30)]

fig = plt.figure(figsize=(12,6))
ax = plt.gca()

my_cmap = cm.jet
scatter_plot = ax.scatter(x, y, s=30, cmap=my_cmap, c=z)

m = cm.ScalarMappable(cmap=my_cmap)
m.set_array(np.array(z))
plt.colorbar(m)

ax.set_yscale('log')
ax.set_xlabel('Effective Temperature [K]')
ax.set_ylabel('Luminosity [L$_{\odot}$]')
ax.yaxis.set_major_formatter(ScalarFormatter())

plt.show()

У вас была правильная идея возиться с форматером: когда вы устанавливаете ось Y в логарифмическом масштабе, форматтер переключается на LogFormatter, поэтому я снова переключился на ScalarFormatter.

Что касается цветовой полосы, я передаю ее в вызов ax.scatter, а затем использую это:

m.set_array(np.array(z))
plt.colorbar(m)

Таким образом я создаю сопоставление между массивом z и цветами: первое значение будет соответствовать цвету внизу и так далее. Я передаю это в цветовую полосу вместе со столбцом z и все. Дополнительную информацию можно найти здесь: https://matplotlib.org/3.1.1/api/cm_api.html.

Только одно: в документах говорится, что диапазон цветов (так что здесь z) обычно должен быть в [0,1]. Здесь это работает, но вы можете нормализовать на всякий случай.

EDIT: как указал @ImportanceOfBeingErnest, точечная диаграмма также является скалярной, поэтому вы также можете использовать это:

scatter_plot.set_array(np.array(z))
plt.colorbar(scatter_plot)
person neko    schedule 30.07.2019
comment
Большое спасибо, это работает почти идеально. Единственная проблема, с которой я столкнулся, заключается в том, что цветная полоса колеблется от -0,1 до 0,1 даже после нормализации. Я ничего не могу найти в документах об этом, поэтому мне было интересно, есть ли у вас какие-либо идеи? если вы не уверены в решении, это не конец света. - person qwerty; 30.07.2019
comment
Какая польза от дополнительного ScalarMappable здесь? Почему бы просто не использовать сам разброс (который для начала является ScalarMappable), например plt.colorbar(scatter_plot)? - person ImportanceOfBeingErnest; 31.07.2019
comment
@ImportanceOfBeingErnest: я этого не понимал. Обновил ответ с вашим предложением. - person neko; 31.07.2019
comment
@qwerty: можете ли вы опубликовать пример данных, которые вы хотите отобразить? я не могу это воспроизвести - person neko; 31.07.2019
comment
@neko Я использую серию панд. Данные, с которыми у меня были проблемы, представляли собой просто числа в диапазоне от -0,3 до 2,7, каждое из которых было связано с точкой разброса. Однако редактирование / комментарий исправили это, и теперь он работает отлично - спасибо! - person qwerty; 01.08.2019

Быстрое решение: вы можете получить галочки и метки с помощью plt.yticks(), а затем заменить метки пустыми строками. Попробуйте добавить следующие строки:

locs, labels = plt.yticks()
plt.yticks(locs, ['' for label in labels])

В качестве альтернативы измените цвет шрифта:

plt.tick_params(axis='y', labelcolor='white')
person Mstaino    schedule 30.07.2019
comment
Спасибо за это, однако оставление строк пустыми приводит к тому, что информация по оси Y вообще отсутствует, и это останавливает работу ylim. Метки отсутствуют, и даже наведение курсора на график не дает информации о значении y. Любая идея, как использовать это, но сохранить фактические данные y? - person qwerty; 30.07.2019
comment
Также попробуйте изменить цвет шрифта (отредактировать); странно, однако, у меня нет проблем с ограничениями, если я вызываю plt.yticks(...) непосредственно перед plt.show(). - person Mstaino; 30.07.2019