График линии Python Matplotlib: изменить цвет линии посередине

Я пытаюсь построить непрерывную линию из ряда координат, но я хотел бы изменить цвет линии в определенных точках.

Input arrays: layerdict['Xc'] = [50.6, 69.4, 69.4, 50.6, **50.6**, **50.2**, 69.8, 69.8, 50.2, **50.2**, **69.053**, 69.12, 69.12] layerdict['Yc'] = [50.6, 50.6, 69.4, 69.4, **50.6**, **50.2**, 50.2, 69.8, 69.8, **50.2**, **50.88**, 50.996, 51.796]

** только для наглядности

Я хочу изменить цвет линии, идущей от (50,6, 50,6) до (50,2,50,2) и (50,2, 50,6) до (69,053,5088) и т. д. Как лучше всего это сделать? У меня есть условный оператор, который может определять условия и вставлять пустые значения или другие операции.

Вот что у меня есть до сих пор.

layerdict = {'Xc': [], 'Yc': [], 'Xt': [], 'Yt': []}

with open(inputfilepath, 'r') as ifile:

for item in ifile:
    gonematch = gonepattern.match(item)
    gtrmatch = gtrpattern.match(item)

    if gonematch:
        tlist = item.split(' ')
        layerdict['Xc'].append(float(tlist[1][1:]))
        layerdict['Yc'].append(float(tlist[2][1:]))
    elif gtrmatch:
        tlist = item.split(' ')
        layerdict['Xt'].append(float(tlist[1][1:]))
        layerdict['Yt'].append(float(tlist[2][1:]))



plt.plot(layerdict['Xc'], layerdict['Yc'], label='linepath', linewidth=3.5)


plt.xlabel('X')
plt.ylabel('Y')
plt.show(block=True)

Пример входного файла будет выглядеть так (просто для справки, откуда я извлекаю координаты)

X10 Y10 A10 B10
X11 Y11 A10
X12.4 Y23.5 A5 ...

person Polyhedronic    schedule 17.08.2018    source источник
comment
Вы можете нарисовать три разные линии, одну для средней части и две для внешних.   -  person Brendan Samek    schedule 18.08.2018
comment
Думал о разделении словаря, но это не очень хорошо масштабируется для большого набора данных.   -  person Polyhedronic    schedule 18.08.2018


Ответы (1)


Я бы использовал замаскированные массивы из модуля ma numpy. Хотя массивы numpy уже лучше, чем простые списки в отношении индексации и математики, маскированные массивы автоматически отображаются только в том случае, если значения маски равны False. Тем не менее, вы по-прежнему можете получить весь немаскированный массив, просто используя свойство данных, поэтому построение сначала всего массива, а затем только его подмножества — это всего лишь вопрос двух почти идентичных команд построения:

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

layerdict = dict()
layerdict['Xc'] = [50.6, 69.4, 69.4, 50.6, 50.6, 50.2, 69.8, 69.8, 50.2, 50.2, 69.053, 69.12, 69.12]
layerdict['Yc'] = [50.6, 50.6, 69.4, 69.4, 50.6, 50.2, 50.2, 69.8, 69.8, 50.2, 50.88, 50.996, 51.796]

highlightmask = np.ones(len(layerdict['Xc'])).astype(bool)
highlightmask[4:6] = highlightmask[9:11] = False

layerdict['Xc'] = ma.array(layerdict['Xc'])
layerdict['Yc'] = ma.array(layerdict['Yc'], mask=highlightmask)

plt.plot(layerdict['Xc'], layerdict['Yc'].data, label='linepath', linewidth=3.5)
plt.plot(layerdict['Xc'], layerdict['Yc'], 'r', linewidth=3.5)
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
person SpghttCd    schedule 18.08.2018
comment
Это работает блестяще. Просто быстрое продолжение, поскольку синие линии пересекаются в нескольких местах, если я изменю маскировку на белый или другой цвет, маска также скроет другую пересекающуюся область. Вопрос в том, могу ли я выборочно замаскировать конкретную линию и не повлиять на другие линии в пересекающихся областях? Больше похоже на разрыв строк? - person Polyhedronic; 19.08.2018
comment
Я не совсем понимаю, что вы имеете в виду под цветом маски. ИМХО есть еще какое-то недопонимание по поводу цели и как ее достичь. Я думал, вы хотите построить полный график и дополнительно выделить некоторые его линии. (Поэтому: красный) Но если вы хотите пропустить эту часть, вы уже сделали бы это с помощью маскирования и только первой команды построения графика. Вам просто нужно инвертировать маску. - person SpghttCd; 19.08.2018
comment
Теперь я понимаю, и ответ, к сожалению: нет. При маскировании вы не маскируете линии, вы маскируете точки - и каждая скрытая точка берет с собой две соседние линии... Таким образом, чтобы скрыть только одну единственную линию, вам нужно добавить вспомогательную точку между двумя определяющими точками линии. скрыть потом только эту новую точку. - person SpghttCd; 19.08.2018
comment
Извините за неясность. Мое продолжение было действительно новым вопросом. Когда я просматривал этот код, я подумал, что было бы эффективно просто разбить эту строку. но спасибо за предложение. Я думаю о наложении нескольких масок, но мне нужно посмотреть, как это работает. - person Polyhedronic; 20.08.2018
comment
Возможно, сейчас было бы интересно поближе взглянуть на то, как считываются данные (эта часть мне пока не ясна). ИМО, в любом случае, это выглядит оптимизируемым, но с вашим циклическим подходом вставка вспомогательных точек не будет большой проблемой. Чего еще совершенно не хватает, так это того, каково условие, если линия должна быть скрыта, или, другими словами, какая пара точек не должна быть соединена. - person SpghttCd; 20.08.2018