Как использовать штриховые негативы в стиле дефалют + цвета линий в Matplotlib / Python? - PullRequest
1 голос
/ 06 мая 2019

При рисовании контурного графика с помощью Python / Matplotlib поведение по умолчанию (для 1 цвета) - штриховые отрицательные значения. Это желаемая особенность для меня. Однако, если я установлю цвет линий, все они будут нарисованы сплошными. Я хотел бы объединить штриховые негативы и пользовательские цвета.

Как нарисовать цветные линии и сохранить стиль негатива?

Ниже я копирую (немного изменяя) пример из этого урока: https://www.oreilly.com/library/view/python-data-science/9781491912126/ch04.html

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

x = np.linspace(0, 5, 50)
y = np.linspace(0, 5, 40)
X, Y = np.meshgrid(x, y)
def f(x, y):
    return np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x)
Z = f(X, Y)

# Default: 1 color, negatives are dashed
plt.contour(X, Y, Z, colors='black')
plt.show()

# Set colormap: all lines are solid
plt.contour(X, Y, Z, cmap='RdBu')
plt.show()

# Set individual colors: all solid lines
plt.contour(X, Y, Z, colors=['b','b','b','r','r','r','r','r'])
plt.show()

Defalut: негативы штриховые. default

Установка цветов с помощью карты цветов: все стало сплошным. Colormap

Установка отдельных цветов: все снова сплошные. Я хотел бы, чтобы синие линии были здесь пунктирными, автоматически, поскольку они являются отрицательными значениями. Individual lines with colors

Ответы [ 2 ]

3 голосов
/ 06 мая 2019

Вот один из способов, которым вы можете это сделать. (Гуру матплотлиб может порекомендовать более простой способ.)

В этом примере используется цветовая карта для установки цветов, а затем изменяется стиль линий после создания контурного графика. Пунктирная линия используется для отрицательных контуров, пунктирная линия для 0 и сплошная линия для положительных.

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


x = np.linspace(0, 5, 50)
y = np.linspace(0, 5, 40)
X, Y = np.meshgrid(x, y)
def f(x, y):
    return np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x)
Z = f(X, Y)

# Contour with a specified colormap.
result = plt.contour(X, Y, Z, cmap='RdBu')

# Override the linestyles based on the levels.
for line, lvl in zip(result.collections, result.levels):
    if lvl < 0:
        line.set_linestyle('--')
    elif lvl == 0:
        line.set_linestyle(':')
    else:
        # Optional; this is the default.
        line.set_linestyle('-')

# Optional--this makes the 0 contour more visible with the
# chosen colormap.
ax = plt.gca()
ax.set_facecolor('#d0d0d0')

plt.show()

Вот результат:

plot

1 голос
/ 06 мая 2019

К сожалению, особенность различных стилей линий для отрицательных значений не предоставляется пользователю.Это связано с тем, используется ли один цвет для линий.Это переключает свойство monochrome, которое, в свою очередь, решает, следует ли изменить стиль линии.

Быстрый взлом заключается в том, чтобы установить для атрибута monochrome значение True и сбросить стили линий.

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 5, 50)
y = np.linspace(0, 5, 40)
X, Y = np.meshgrid(x, y)
def f(x, y):
    return np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x)
Z = f(X, Y)


cntr = plt.contour(X, Y, Z, cmap='RdBu')
cntr.monochrome = True
for col, ls in zip(cntr.collections, cntr._process_linestyles()):
    col.set_linestyle(ls)

plt.show()

enter image description here

Сздесь используется закрытый атрибут ._process_linestyles(), поэтому не рекомендуется использовать его в рабочем коде;но вместо этого используйте @ WarrenWeckesser's answer или указанную ниже опцию.

Здесь я хотел бы указать на опцию установки linestyles априори, в зависимости от уровней:

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

x = np.linspace(0, 5, 50)
y = np.linspace(0, 5, 40)
X, Y = np.meshgrid(x, y)
def f(x, y):
    return np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x)
Z = f(X, Y)


loc = matplotlib.ticker.MaxNLocator(7)
lvls = loc.tick_values(Z.min(), Z.max())
cntr = plt.contour(X, Y, Z, levels=lvls, cmap='RdBu', 
                   linestyles=np.where(lvls >= 0, "-", "--"))

plt.show()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...