'Creating a custom colorbar for battery levels

Using a simulation, I was able to construct a list of battery levels in percentage decreasing over time as you can see here :

enter image description here

I was already able to dispay the battery levels depending on the time using matplotlib pyplot. This list has a size of 1944 elements and I would like to know if there is a possibility to display these battery levels depending on the time using a custom colorbar from green (100% of battery) to red (around 15% of battery) to black (below 15% of battery which is critical).



Solution 1:[1]

You can use a LinearSegmentedColormap.from_list() using tuples of values and colors. Here is an example using a seaborn heatmap to show how it works:

import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
import seaborn as sns

cmap = LinearSegmentedColormap.from_list('', [(0, 'black'), (.15, 'black'), (.15, 'crimson'), (1, 'limegreen')])

fig, ax = plt.subplots(figsize=(5, 10))
sns.heatmap(np.linspace(100, 0, 30).reshape(-1, 1), annot=True, fmt='.2f', cmap=cmap, ax=ax)

using a LinearSegmentedColormap from list

PS: plt.plot() can't be used with a colormap. A curve has just one given color. You could use plt.scatter(temps_total_simulation, pourcentage_total, c=pourcentage_total, cmap=cmap, vmin=0, vmax=100) to individual points.

In matplotlib's tutorial, there is an example to split a curve into individual line segments, and then color these segments. Note that there is one segment less than there are points, as each segment connects two points. The mean of the percentage values of the endpoints of a segment could define the segment's color:

import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
from matplotlib.collections import LineCollection
import numpy as np

cmap = LinearSegmentedColormap.from_list('', [(0, 'black'), (.15, 'black'), (.15, 'crimson'), (1, 'limegreen')])

fig, ax = plt.subplots(figsize=(12, 5))
temps_total_simulation = np.arange(1000)
pourcentage_total = np.random.randn(len(temps_total_simulation)).cumsum()
pourcentage_total -= pourcentage_total.min()
pourcentage_total = pourcentage_total / pourcentage_total.max() * 100
# ax.scatter(temps_total_simulation, pourcentage_total, s=3, c=pourcentage_total, cmap=cmap)

pnts = np.c_[temps_total_simulation, pourcentage_total]
segments = np.c_[pnts[:-1], pnts[1:]].reshape(-1, 2, 2)
linecol = LineCollection(segments, cmap=cmap, norm=plt.Normalize(0, 100))
linecol.set_array(
    (pourcentage_total[:-1] + pourcentage_total[1:]) / 2)  # use the mean percentage for colloring the segment
linecol.set_linewidth(1)
ax.add_collection(linecol)

ax.set_xlim(temps_total_simulation[0], temps_total_simulation[-1])
ax.set_ylim(0, 100)

plt.show()

coloring line segments with the listedcolormap

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1