-1

I did try other solutions that are similar to my question but I did not succeed, python: how to plot one line in different colors

Color by Column Values in Matplotlib

pandas plot one line graph with color change on column

I want the plot to change color when the values changes, for instance, if the emotion is 0, it will stay black, if the value changes to 1, the color will be red, if the value is 2, the color will be blue and etc. The progress I've made so far is attached to this question, thank you in advance.

random_emotions = [0,0,0,0,0,0,0,1,2,3,2,1,2,1,
           2,3,2,2,2,2,1,1,2,3,3,3,3,3,3,4,
           4,4,4,4,2,1,2,2,1,2,3,4,0,0,0,0,0]
random_emotions = np.array(random_emotions)

EmotionsInNumber = random_emotions

x = np.array(list(range(0,len(EmotionsInNumber))))

Angry = np.ma.masked_where(EmotionsInNumber == 0,EmotionsInNumber)
Fear = np.ma.masked_where(EmotionsInNumber == 1,EmotionsInNumber)
Happy  = np.ma.masked_where(EmotionsInNumber == 2,EmotionsInNumber)
Neutral = np.ma.masked_where(EmotionsInNumber == 3, EmotionsInNumber)
Sad = np.ma.masked_where(EmotionsInNumber == 4,EmotionsInNumber)

fig, ax = plt.subplots()
ax.plot(x, Angry,linewidth = 4, color = 'black')
ax.plot(x, Fear,linewidth = 4, color = 'red')
ax.plot(x, Happy,linewidth = 4, color = 'blue')
ax.plot(x, Neutral,linewidth = 4, color = 'yellow')
ax.plot(x, Sad,linewidth = 4, color = 'green')
ax.legend(['Angry','Fear','Happy','Neutral','Sad',])  
ax.set_title("Emotion Report of ")

plt.show()

This is the result that I am getting

The color is not changed accordingly, the legends are wrong and I have no idea how to fix this.

matplotlib color line by "value" [duplicate] This 'matplotlib color line by "value" [duplicate]' is the closest I got, but when the color changes to cyan on index 1 and 5, the blue should be empty but it keeps plotting both blue and cyan. This is because the dataframe is grouped by 'colors' but it should not plot blue on 1 and 5 and cyan on 2,3,4 on the graph.

2
  • Your other question was closed because the duplicates show various ways to do this. This question is exactly the same as the previous question, and shows no effort to use any of the information from the duplicates. SO is not a coding service, and stating that the duplicates did not work, is insufficient. Your question must show which duplicate(s) you tried, and how that did not work, otherwise, it's likely the question will be closed again. Commented Oct 7, 2021 at 18:44
  • What about them didn't work? Show what you did Commented Oct 7, 2021 at 18:57

1 Answer 1

-1
  • The main question will be closed as a duplicate to this answer of this question
    • The code is explained in the duplicates.
  • When a question is marked as a duplicate and you don't agree, it is your responsibility to show with code, exactly how you tried to incorporate the duplicate, and what's not working.
  • SO is a repository of questions and answers, which can be used as a reference to answer new questions. When a question is answered by code in an existing question/answer, it is up to you to do the work.
  • Since it's a duplicate, this answer has been added as a community wiki.
from matplotlib.lines import Line2D
import pandas as pd
import matplotlib.pyplot as plt

# set up the dataframe to match the duplicate
random_emotions = [0,0,0,0,0,0,0,1,2,3,2,1,2,1, 2,3,2,2,2,2,1,1,2,3,3,3,3,3,3,4, 4,4,4,4,2,1,2,2,1,2,3,4,0,0,0,0,0]

df = pd.DataFrame({'val': random_emotions})

# map values is covered in duplicate
emotion_dict = {0: 'Angry', 1: 'Fear', 2: 'Happy', 3: 'Neutral', 4: 'Sad'}
color_dict = {0: 'k', 1: 'r', 2: 'b', 3: 'y', 4: 'g'}
df['emotion'] = df.val.map(emotion_dict)
df['color'] = df.val.map(color_dict)

# everything else from here is a duplicated

df['change'] = df.val.ne(df.val.shift().bfill()).astype(int)
df['subgroup'] = df['change'].cumsum()

df.index += df['subgroup'].values

first_i_of_each_group = df[df['change'] == 1].index
for i in first_i_of_each_group:
    # Copy next group's first row to current group's last row
    df.loc[i-1] = df.loc[i]
    # But make this new row part of the current group
    df.loc[i-1, 'subgroup'] = df.loc[i-2, 'subgroup']
# Don't need the change col anymore
df.drop('change', axis=1, inplace=True)
df.sort_index(inplace=True)
# Create duplicate indexes at each subgroup border to ensure the plot is continuous.
df.index -= df['subgroup'].values

fig, ax = plt.subplots(figsize=(15, 4))
for k, g in df.groupby('subgroup'):
    g.plot(ax=ax, y='val', color=g['color'].values[0], marker='.', legend=False, xticks=df.index)

ax.margins(x=0)

# create custom legend is covered in duplicate
custom_lines = [Line2D([0], [0], color=color, lw=4) for color in color_dict.values()]
_ = ax.legend(title='Emotion', handles=custom_lines, labels=emotion_dict.values(), bbox_to_anchor=(1, 1.02), loc='upper left')

enter image description here

# display(df.T)
             0      1      2      3      4      5      6     7     7      8      8        9        9      10     10    11    11     12     12    13    13     14     14       15       15     16     16     17     18     19    20    20    21     22     22       23       23       24       25       26       27       28   29   29   30   31   32   33     34     34    35    35     36     36     37    38    38     39     39       40       40   41   41     42     42     43     44     45     46
val           0      0      0      0      0      0      0     1     1      2      2        3        3      2      2     1     1      2      2     1     1      2      2        3        3      2      2      2      2      2     1     1     1      2      2        3        3        3        3        3        3        3    4    4    4    4    4    4      2      2     1     1      2      2      2     1     1      2      2        3        3    4    4      0      0      0      0      0      0
emotion   Angry  Angry  Angry  Angry  Angry  Angry  Angry  Fear  Fear  Happy  Happy  Neutral  Neutral  Happy  Happy  Fear  Fear  Happy  Happy  Fear  Fear  Happy  Happy  Neutral  Neutral  Happy  Happy  Happy  Happy  Happy  Fear  Fear  Fear  Happy  Happy  Neutral  Neutral  Neutral  Neutral  Neutral  Neutral  Neutral  Sad  Sad  Sad  Sad  Sad  Sad  Happy  Happy  Fear  Fear  Happy  Happy  Happy  Fear  Fear  Happy  Happy  Neutral  Neutral  Sad  Sad  Angry  Angry  Angry  Angry  Angry  Angry
color         k      k      k      k      k      k      k     r     r      b      b        y        y      b      b     r     r      b      b     r     r      b      b        y        y      b      b      b      b      b     r     r     r      b      b        y        y        y        y        y        y        y    g    g    g    g    g    g      b      b     r     r      b      b      b     r     r      b      b        y        y    g    g      k      k      k      k      k      k
subgroup      0      0      0      0      0      0      0     0     1      1      2        2        3      3      4     4     5      5      6     6     7      7      8        8        9      9     10     10     10     10    10    11    11     11     12       12       13       13       13       13       13       13   13   14   14   14   14   14     14     15    15    16     16     17     17    17    18     18     19       19       20   20   21     21     22     22     22     22     22
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much for the help, I will improve my questions and show everything I have done on the duplicates next time.
@sjsu You're welcome.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.