0

I am trying to plot a continuous line from a series of coordinates but I would like to change the line color at specific junctures.

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]

** is just for visual purposes

I want to change the color of the line that goes from (50.6, 50.6) to (50.2,50.2) and (50.2, 50.6) to (69.053,5088) and so on... What is the best way to do this ? I have a conditional statement that can detect then conditions and insert blank values or other operations

Here is what I have so far.

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)

A sample Input file will look like this (just for reference, where I am extracting the coordinates from)

X10 Y10 A10 B10
X11 Y11 A10
X12.4 Y23.5 A5 ...
Polyhedronic
  • 63
  • 1
  • 1
  • 10

1 Answers1

2

I'd use masked arrays from the ma module of numpy. While numpy arrays would already be better than simple lists with regards to indexing and math, masked arrays are automatically plotted only where the mask values are False. However, you still can retrieve the whole unmasked array simply by using the data property, so plotting firstly the whole array and then only a subset is just a matter of two almost identical plot commands:

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()
SpghttCd
  • 10,510
  • 2
  • 20
  • 25
  • This works brilliantly. Just a quick follow up, since the blue lines are intersecting at a few places, if I change the masking to white or another color, the mask hides the other intersecting region as well. The question is can i selectively mask a particular line and not affect the other lines in the intersecting regions ? More like putting a break in the lines ? – Polyhedronic Aug 19 '18 at 17:58
  • I don't really understand what you mean by a color of a mask. IMHO there is still some misunderstanding about the target and how to achieve it. I thought, you wanted to plot a complete graph and additionally wanted to highlight some of its lines. (Therefore: red) But if you want to leave this part out, you'd be already done by masking and the first plot command only . You'd just have to kind of invert the mask. – SpghttCd Aug 19 '18 at 19:36
  • 1
    Now I understand, and the answer is unfortunately: no. With the masking approach you do not mask lines, you mask points - and every hidden point takes its two neighboured lines with it... So for hiding only one single line you'd have to add a helper point betwern the two line defining points to hide then only this new point. – SpghttCd Aug 19 '18 at 20:15
  • Sorry for not being clear. My follow up was indeed a new question. As I was going through this code, I thought it would be efficient to just break this line up. but thanks for the suggestion. I am thinking about overlaying multiple masks but will have to see how that works. – Polyhedronic Aug 19 '18 at 23:29
  • Perhaps it would be interesting now to have a closer look at how the data is read in (this part is still not clear to me). IMO it looks optimizable anyway, but with your looping approach, inserting helper points would not be a big thing. What is still completely lacking is: what is the condition if a line should be hidden or in other words, which pair of points should not be connected. – SpghttCd Aug 20 '18 at 06:16