Search code examples
pythonpandasmatplotlibcolorsvalueerror

conditional line color results in ValueError


I am trying to plot a linegraph with matplotlib.pytplot and have a dataframe df with the shape (42,7). The dataframe has the following structur (only showing relevant columns):

timepoint   value   point
2021-01-01   10      0
2021-02-01   20      0
....
2021-11-01   10      0
2021-12-01   50      1
2022-01-01   60      1
...

I try to plot conditional color in the following way (that each value with point=0 is blue and each value with point=1 is red):

import numpy as np
col = np.where(df['point'] == 0, 'b', 'r')


plt.plot(df['timepoint'], df['value'], c=col)
plt.show()

and I get the error massage:

ValueError: array(['b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r'], dtype='<U1') is not a valid value for color

When I look at this question ValueError: Invalid RGBA argument: What is causing this error? , I don't find any solution as the shape of my color array is: col.shape is (42, )


Solution

  • I don't think you can use np.where here to define the colors of your line graph (as they did here with a scatter one) because in the former, the c parameter expects a single color for the whole line while in the latter, you can provide an array of colors that will be mapped to the points.

    So, here is one possible option to address that :

    (_, p0), (_, others) = df.groupby(df["point"].eq(0), sort=False)
    
    plt.plot(p0.timepoint, p0.value, c="b", label="0 Points")
    plt.plot(others.timepoint, others.value, c="r", label="Others")
    
    plt.legend()
    plt.show();
    

    Or with pivot / plot :

    other_points = df["point"].loc[lambda s: s.ne(0)].unique()
    
    (
        df.pivot(index="timepoint", columns="point", values="value")
            .plot(style={0: "b", **{k: "r" for k in other_points}})
    )
    

    Output :

    enter image description here