База научных обозначений Python matplotlib colorbar

Я пытаюсь настроить цветовую панель на своих графиках контура matpllotlib. Хотя я могу использовать научную нотацию, я пытаюсь изменить ее основу - по сути, так, чтобы мои отметки находились в диапазоне (-100,100), а не (-10,10).

Например, получается простой сюжет ...

import numpy as np
import matplotlib.pyplot as plt

z = (np.random.random((10,10)) - 0.5) * 0.2

fig, ax = plt.subplots()
plot = ax.contourf(z)
cbar = fig.colorbar(plot)

cbar.formatter.set_powerlimits((0, 0))
cbar.update_ticks()

plt.show()

вот так:

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

Однако я бы хотел, чтобы метка над шкалой палитры была 1e-2, а числа находились в диапазоне от -10 до 10.

Как мне это сделать?


person John    schedule 10.04.2017    source источник


Ответы (2)


Возможным решением может быть подкласс ScalarFormatter и исправление порядка величины, как в этом вопросе: Установить научное представление с фиксированной степенью и значащими цифрами для нескольких подзаголовков

Затем вы должны вызвать это средство форматирования с порядком величины в качестве аргумента order, OOMFormatter(-2, mathText=False). mathText установлено значение false, чтобы получить обозначение из вопроса, например  введите здесь описание изображения , установив для него значение True, даст  введите описание изображения здесь .

Затем вы можете установить средство форматирования на цветовую панель с помощью аргумента цветовой шкалы format.

import numpy as np; np.random.seed(0)
import matplotlib.pyplot as plt
import matplotlib.ticker

class OOMFormatter(matplotlib.ticker.ScalarFormatter):
    def __init__(self, order=0, fformat="%1.1f", offset=True, mathText=True):
        self.oom = order
        self.fformat = fformat
        matplotlib.ticker.ScalarFormatter.__init__(self,useOffset=offset,useMathText=mathText)
    def _set_order_of_magnitude(self):
        self.orderOfMagnitude = self.oom
    def _set_format(self, vmin=None, vmax=None):
        self.format = self.fformat
        if self._useMathText:
             self.format = r'$\mathdefault{%s}$' % self.format


z = (np.random.random((10,10)) - 0.5) * 0.2

fig, ax = plt.subplots()
plot = ax.contourf(z)
cbar = fig.colorbar(plot, format=OOMFormatter(-2, mathText=False))

plt.show()

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

Для версий matplotlib ‹3.1 класс должен выглядеть так:

class OOMFormatter(matplotlib.ticker.ScalarFormatter):
    def __init__(self, order=0, fformat="%1.1f", offset=True, mathText=True):
        self.oom = order
        self.fformat = fformat
        matplotlib.ticker.ScalarFormatter.__init__(self,useOffset=offset,useMathText=mathText)
    def _set_orderOfMagnitude(self, nothing):
        self.orderOfMagnitude = self.oom
    def _set_format(self, vmin, vmax):
        self.format = self.fformat
        if self._useMathText:
            self.format = '$%s$' % matplotlib.ticker._mathdefault(self.format)
person ImportanceOfBeingErnest    schedule 10.04.2017
comment
Могут ли люди еще воспроизвести это? - person leb; 23.04.2020
comment
@leb Да, я очень хорошо умею это воспроизводить! - person olenscki; 26.06.2021

Подобно тому, что описал @ImportanceOfBeingErnes, вы можете использовать FuncFormatter (документы ), которому вы просто передаете функцию для определения меток галочки. Это удаляет автоматическое создание заголовка 1e-2 для вашей палитры, но я полагаю, что вы можете вручную добавить его обратно (у меня были проблемы с этим, хотя я смог добавить его сбоку). Используя FuncFormatter, вы можете просто сгенерировать строковые значения галочки, что имеет то преимущество, что вам не нужно принимать способ, которым, по мнению Python, должно отображаться число.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as tk

z = (np.random.random((10,10)) - 0.5) * 0.2

levels = list(np.linspace(-.1,.1,9))

fig, ax = plt.subplots()
plot = ax.contourf(z, levels=levels)

def my_func(x, pos):
    label = levels[pos]
    return str(label*100)

fmt1 = tk.FuncFormatter(my_func)

cbar = fig.colorbar(plot, format=fmt1)
cbar.set_label("1e-2")

plt.show()

Это сгенерирует сюжет, который выглядит следующим образом.

Контурная диаграмма

person user2027202827    schedule 10.04.2017