как использовать cycler в matplotlib? [Дубликат]

Существует несколько способов сделать это, и из вашего вопроса это не ясно, что вам нужно.

1. Если вам нужна переменная среды, которая должна быть определена PER TASK ONLY, вы делаете это:

- hosts: dev
  tasks:
    - name: Echo my_env_var
      shell: "echo $MY_ENV_VARIABLE"
      environment:
        MY_ENV_VARIABLE: whatever_value

    - name: Echo my_env_var again
      shell: "echo $MY_ENV_VARIABLE"
blockquote>

Обратите внимание, что MY_ENV_VARIABLE доступно ТОЛЬКО для первой задачи, environment не устанавливайте его постоянно на вашей системе.

TASK: [Echo my_env_var] ******************************************************* 
changed: [192.168.111.222] => {"changed": true, "cmd": "echo $MY_ENV_VARIABLE", ... "stdout": "whatever_value"}

TASK: [Echo my_env_var again] ************************************************* 
changed: [192.168.111.222] => {"changed": true, "cmd": "echo $MY_ENV_VARIABLE", ... "stdout": ""}

Надеемся, что скоро использование environment также будет возможно на уровне игры, а не только на уровне задачи, как указано выше. В настоящее время для этой функции в GitHub от Ansible открыт запрос на перенос: https://github.com/ansible/ansible/pull/8651

UPDATE: теперь он слит с января 2, 2015 год.

2. Если вам нужна постоянная переменная среды + система в целом / только для определенного пользователя

Вы должны посмотреть, как вы это делаете в своем дистрибутиве / оболочке Linux, для этого есть несколько мест. Например, в Ubuntu вы определяете это в файлах, например:

  • ~/.profile
  • /etc/environment
  • /etc/profile.d directory
  • ...

Вы найдете здесь документы Ubuntu: https://help.ubuntu.com/community/EnvironmentVariables

В конце концов для установки переменной среды в ex. Ubuntu вы можете просто использовать модуль lineinfile от Ansible и добавить нужную строку в определенный файл. Обратитесь к своим документам ОС, чтобы узнать, где их добавить, чтобы сделать их постоянными.

76
задан mwaskom 12 December 2012 в 03:50
поделиться

6 ответов

Доступ к итератору цикла цвета

Для доступа к базовому итератору нет «пользовательского» (a.k.a. «public») метода, но вы можете получить к нему доступ через «частные» (по соглашению) методы. Однако вы не сможете получить состояние iterator, не изменяя его.

Установка цветового цикла

Быстрая сторона: вы можете установить цвет / свойство в различными способами (например, ax.set_color_cycle в версиях & lt; 1,5 или ax.set_prop_cycler в> = 1,5). Посмотрите пример здесь для версии 1.5 или выше или предыдущий стиль здесь .

Доступ к базовому итератору

Однако, несмотря на то, что для доступа к итерабельному нет доступа к public-обращению, вы можете получить к нему доступ для данного объекта осей (ax) через экземпляр класса помощника _get_lines. ax._get_lines - это прикосновение, смутно названное, но это закулисное оборудование, которое позволяет команде plot обрабатывать все нечетные и разнообразные способы вызова plot. Помимо всего прочего, это то, что отслеживает, какие цвета автоматически назначаются. Аналогично, есть ax._get_patches_for_fill для управления циклическим использованием цветов заливки по умолчанию и свойств патча.

Во всяком случае, цикл цикла iterable является ax._get_lines.color_cycle для строк и ax._get_patches_for_fill.color_cycle для патчей. В matplotlib> = 1.5 это изменилось на , используя библиотеку cycler , и итерабельность называется prop_cycler вместо color_cycle и дает свойства dict вместо цвета .

В общем, вы сделали бы что-то вроде:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
color_cycle = ax._get_lines.color_cycle
# or ax._get_lines.prop_cycler on version >= 1.5
# Note that prop_cycler cycles over dicts, so you'll want next(cycle)['color']

Вы не можете просмотреть состояние iterator

Однако, этот объект является «голой» iterator. Мы можем легко получить следующий элемент (например, next_color = next(color_cycle), но это означает, что следующий цвет после этого будет тем, что будет построено. По дизайну, нет способа получить текущее состояние итератора без

В v1.5 или выше было бы неплохо получить объект cycler, который использовался, поскольку мы могли бы вывести его текущее состояние. Однако сам объект cycler доступный (публично или конфиденциально) в любом месте. Вместо этого доступен только экземпляр itertools.cycle, созданный из объекта cycler. В любом случае, нет способа добраться до базового состояния цикла color / property.

Соответствует цвету ранее нанесенного объекта вместо

В вашем случае это похоже на то, что вы хотите соответствовать цвету того, что было только что построено. Вместо того, чтобы пытаться определить, какой цвет / свойство будет установлен цвет / etc вашего нового элемента на основе свойств того, что нанесено на экран.

Например, в случае, описанном вами, я бы сделал что-то вроде этого:

import matplotlib.pyplot as plt
import numpy as np

def custom_plot(x, y, **kwargs):
    ax = kwargs.pop('ax', plt.gca())
    base_line, = ax.plot(x, y, **kwargs)
    ax.fill_between(x, 0.9*y, 1.1*y, facecolor=base_line.get_color(), alpha=0.5)

x = np.linspace(0, 1, 10)
custom_plot(x, x)
custom_plot(x, 2*x)
custom_plot(x, -x, color='yellow', lw=3)

plt.show()

enter image description here [/g9]

Это не единственный способ, но его чище, чем пытаться получить цвет начерченной строки раньше, в этом случае.

86
ответ дан IanS 27 August 2018 в 11:53
поделиться

Конечно, это будет сделано.

#rainbow

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0,2*np.pi)
ax= plt.subplot(1,1,1)
ax.plot(np.sin(x))
ax.plot(np.cos(x))

rainbow = ax._get_lines.color_cycle
print rainbow
for i, color in enumerate(rainbow):
    if i<10:
        print color,

Дает:

<itertools.cycle object at 0x034CB288>
r c m y k b g r c m

Вот функция itertools, которую matplotlib использует itertools.cycle

Редактировать: Спасибо за комментарий, кажется, что копировать итератор невозможно. Идея состояла бы в том, чтобы сбрасывать полный цикл и отслеживать, какое значение вы используете, позвольте мне вернуться к этому.

Edit2: Allright, это даст вам следующий цвет и сделает новый итератор, который ведет себя так, как будто следующий не был вызван. Это не сохраняет порядок окраски, просто следующее значение цвета, я оставляю это для вас.

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

#rainbow

import matplotlib.pyplot as plt
import numpy as np
import collections
import itertools

x = np.linspace(0,2*np.pi)
ax= plt.subplot(1,1,1)


def create_rainbow():
    rainbow = [ax._get_lines.color_cycle.next()]
    while True:
        nextval = ax._get_lines.color_cycle.next()
        if nextval not in rainbow:
            rainbow.append(nextval)
        else:
            return rainbow

def next_color(axis_handle=ax):
    rainbow = create_rainbow()
    double_rainbow = collections.deque(rainbow)
    nextval = ax._get_lines.color_cycle.next()
    double_rainbow.rotate(-1)
    return nextval, itertools.cycle(double_rainbow)


for i in range(1,10):
    nextval, ax._get_lines.color_cycle = next_color(ax)
    print "Next color is: ", nextval
    ax.plot(i*(x))


plt.savefig("SO_rotate_color.png")
plt.show()

Консоль

Next color is:  g
Next color is:  c
Next color is:  y
Next color is:  b
Next color is:  r
Next color is:  m
Next color is:  k
Next color is:  g
Next color is:  c

Rotate color [/g1]

6
ответ дан arynaq 27 August 2018 в 11:53
поделиться

Я просто хочу добавить, что сказал @Andi выше. Поскольку color_cycle устарел в matplotlib 1.5, вы должны использовать prop_cycler, однако решение Andi (ax._get_lines.prop_cycler.next()['color']) вернуло мне эту ошибку:

AttributeError: 'itertools.cycle' объект не имеет атрибута «next»

Код, который работал для меня, был: next(ax._get_lines.prop_cycler), который на самом деле не за горами исходного ответа @ joe-kington.

Лично я столкнулся с этой проблемой при создании оси doublex (), которая сбросила цветовой цикл. Мне нужно было правильно настроить цвет, потому что я использовал style.use('ggplot'). Может быть, есть более простой / лучший способ сделать это, поэтому не стесняйтесь меня исправлять.

3
ответ дан Carson 27 August 2018 в 11:53
поделиться

Примечание. В последних версиях matplotlib (> = 1.5) _get_lines изменилось. Теперь вам нужно использовать next(ax._get_lines.prop_cycler)['color'] в Python 2 или 3 (или ax._get_lines.prop_cycler.next()['color'] в Python 2 ), чтобы получить следующий цвет из цветового цикла.

По возможности используйте более прямой подход, показанный в нижней части ответа @ joe-kington. Поскольку _get_lines не обращен к API, в будущем он может снова измениться в обратном порядке.

13
ответ дан Community 27 August 2018 в 11:53
поделиться

Поскольку matplotlib использует itertools.cycle, мы можем реально просмотреть весь цикл цвета, а затем восстановить итератор в его предыдущее состояние:

def list_from_cycle(cycle):
    first = next(cycle)
    result = [first]
    for current in cycle:
        if current == first:
            break
        result.append(current)

    # Reset iterator state:
    for current in cycle:
        if current == result[-1]:
            break
    return result

Это должно вернуть список без изменения состояния итератора .

Используйте его с matplotlib> = 1.5:

>>> list_from_cycle(ax._get_lines.prop_cycler)
[{'color': 'r'}, {'color': 'g'}, {'color': 'b'}]

или с matplotlib & lt; 1.5:

>>> list_from_cycle(ax._get_lines.color_cycle)
['r', 'g', 'b']
1
ответ дан freidrichen 27 August 2018 в 11:53
поделиться

Вот способ, который работает в 1.5, который, мы надеемся, будет перспективным, поскольку он не полагается на методы, добавленные с подчеркиваниями:

colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]

Это даст вам список цветов, определенных в порядок для настоящего стиля.

9
ответ дан Mike DePalatis 27 August 2018 в 11:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: