Python:如果超出特定范围,是不是可以更改绘图中的线条颜色?
Posted
技术标签:
【中文标题】Python:如果超出特定范围,是不是可以更改绘图中的线条颜色?【英文标题】:Python: Is it possible to change line color in a plot if exceeds a specific range?Python:如果超出特定范围,是否可以更改绘图中的线条颜色? 【发布时间】:2015-07-19 05:57:30 【问题描述】:当值超过某个 y 值时,是否可以更改绘图中的线条颜色? 示例:
import numpy as np
import matplotlib.pyplot as plt
a = np.array([1,2,17,20,16,3,5,4])
plt.plt(a)
这个给出了以下内容:
我想可视化超过 y=15 的值。如下图:
或者类似的东西(带循环线型)::
有可能吗?
【问题讨论】:
您要制作控制图吗?如果是这样 - 这个问题的答案可能会有所帮助:***.com/questions/9962114/control-charts-in-python。可以做你想做的事 - 如果这个问题有帮助,很好 - 如果没有,请告诉我们。 见matplotlib.org/examples/pylab_examples/multicolored_line.html 对于更复杂的数据插值方法,请参阅***.com/questions/46213266/… 【参考方案1】:定义一个辅助函数(这是一个简单的函数,可以添加更多的花里胡哨)。此代码是对文档中this example 的轻微重构。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from matplotlib.colors import ListedColormap, BoundaryNorm
def threshold_plot(ax, x, y, threshv, color, overcolor):
"""
Helper function to plot points above a threshold in a different color
Parameters
----------
ax : Axes
Axes to plot to
x, y : array
The x and y values
threshv : float
Plot using overcolor above this value
color : color
The color to use for the lower values
overcolor: color
The color to use for values over threshv
"""
# Create a colormap for red, green and blue and a norm to color
# f' < -0.5 red, f' > 0.5 blue, and the rest green
cmap = ListedColormap([color, overcolor])
norm = BoundaryNorm([np.min(y), threshv, np.max(y)], cmap.N)
# Create a set of line segments so that we can color them individually
# This creates the points as a N x 1 x 2 array so that we can stack points
# together easily to get the segments. The segments array for line collection
# needs to be numlines x points per line x 2 (x and y)
points = np.array([x, y]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
# Create the line collection object, setting the colormapping parameters.
# Have to set the actual values used for colormapping separately.
lc = LineCollection(segments, cmap=cmap, norm=norm)
lc.set_array(y)
ax.add_collection(lc)
ax.set_xlim(np.min(x), np.max(x))
ax.set_ylim(np.min(y)*1.1, np.max(y)*1.1)
return lc
使用示例
fig, ax = plt.subplots()
x = np.linspace(0, 3 * np.pi, 500)
y = np.sin(x)
lc = threshold_plot(ax, x, y, .75, 'k', 'r')
ax.axhline(.75, color='k', ls='--')
lc.set_linewidth(3)
和输出
如果您只想让标记改变颜色,请使用相同的 norm 和 cmap 并将它们传递给 scatter as
cmap = ListedColormap([color, overcolor])
norm = BoundaryNorm([np.min(y), threshv, np.max(y)], cmap.N)
sc = ax.scatter(x, y, c=c, norm=norm, cmap=cmap)
【讨论】:
我可以知道如何以与上述情况相同的方式从 CSV 文件中绘制值。在 CSV 中,索引应位于x-axis
上,另一列中的值应位于 y-axis
上。【参考方案2】:
不幸的是,matplotlib 没有简单的选项来更改仅部分线条的颜色。我们将不得不自己编写逻辑。诀窍是将线切割成线段的集合,然后为每个线段分配颜色,然后绘制它们。
from matplotlib import pyplot as plt
from matplotlib.collections import LineCollection
import numpy as np
# The x and y data to plot
y = np.array([1,2,17,20,16,3,5,4])
x = np.arange(len(y))
# Threshold above which the line should be red
threshold = 15
# Create line segments: 1--2, 2--17, 17--20, 20--16, 16--3, etc.
segments_x = np.r_[x[0], x[1:-1].repeat(2), x[-1]].reshape(-1, 2)
segments_y = np.r_[y[0], y[1:-1].repeat(2), y[-1]].reshape(-1, 2)
# Assign colors to the line segments
linecolors = ['red' if y_[0] > threshold and y_[1] > threshold else 'blue'
for y_ in segments_y]
# Stamp x,y coordinates of the segments into the proper format for the
# LineCollection
segments = [zip(x_, y_) for x_, y_ in zip(segments_x, segments_y)]
# Create figure
plt.figure()
ax = plt.axes()
# Add a collection of lines
ax.add_collection(LineCollection(segments, colors=linecolors))
# Set x and y limits... sadly this is not done automatically for line
# collections
ax.set_xlim(0, 8)
ax.set_ylim(0, 21)
您的第二个选项要容易得多。我们首先画线,然后将标记添加为散点图:
from matplotlib import pyplot as plt
import numpy as np
# The x and y data to plot
y = np.array([1,2,17,20,16,3,5,4])
x = np.arange(len(y))
# Threshold above which the markers should be red
threshold = 15
# Create figure
plt.figure()
# Plot the line
plt.plot(x, y, color='blue')
# Add below threshold markers
below_threshold = y < threshold
plt.scatter(x[below_threshold], y[below_threshold], color='green')
# Add above threshold markers
above_threshold = np.logical_not(below_threshold)
plt.scatter(x[above_threshold], y[above_threshold], color='red')
【讨论】:
【参考方案3】:基本上@RaJa 提供了解决方案,但我认为您可以通过在 numpy 中使用掩码数组来执行相同的操作,而无需加载额外的包(熊猫):
import numpy as np
import matplotlib.pyplot as plt
a = np.array([1,2,17,20,16,3,5,4])
# use a masked array to suppress the values that are too low
a_masked = np.ma.masked_less_equal(a, 15)
# plot the full line
plt.plot(a, 'k')
# plot only the large values
plt.plot(a_masked, 'r', linewidth=2)
# add the threshold value (optional)
plt.axhline(15, color='k', linestyle='--')
plt.show()
结果:
【讨论】:
我可以知道如何以与上述情况相同的方式从 CSV 文件中绘制值。在 CSV 中,索引应位于x-axis
上,另一列中的值应位于 y-axis
上。【参考方案4】:
我不知道matplolib中是否有内置函数。但是您可以将您的 numpy 数组转换为 pandas 系列,然后将 plot 函数与布尔选择/屏蔽结合使用。
import numpy as np
import pandas as pd
a = np.array([1,2,17,20,16,3,5,4])
aPandas = pd.Series(a)
aPandas.plot()
aPandas[aPandas > 15].plot(color = 'red')
【讨论】:
以上是关于Python:如果超出特定范围,是不是可以更改绘图中的线条颜色?的主要内容,如果未能解决你的问题,请参考以下文章
如果超出范围,防止 jQuery UI datepicker 更改文本字段的值
Python如何打出“删除列表特定范围的元素,若超出范围,则输出错误”这个代码?
Python matplotlib更改超出颜色条范围的值的默认颜色