'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 :
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)
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()
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 |



