如何为直方图 matplotlib 的选定范围着色?
How to colour selected range of histogram matplotlib?
我有一个名为 prices
的数据,我使用 prices.tail(1)
构建直方图。
我还有一些变量:left_border = 341.086
、right_border = 437.177
、line_length = 1099
。
下一个代码:
plt.figure(figsize=(9,6))
plt.hist(prices.tail(1), bins = 400)
x2 = [left_border,left_border]
y2 = [0, line_length]
plt.plot(x2, y2, color = 'green')
x3 = [right_border, right_border]
y3 = [0, line_length]
plt.plot(x3, y3, color = 'green')
plt.show()
产生输出:
如何渐变地为绿色边界之间的直方图部分和绿色边界之外的部分着色?还要选择接近绿色边框的垃圾箱并将它们变成另一种颜色?
谢谢。
这里'gradiently'的确切含义我不清楚。这里有一些想法,可以作为创建所需解决方案的基础。
hist
returns 每个箱子的值,箱子的限制和绘制的补丁;你可以根据它们的平均 x 位置为补丁着色
- 要创建类似渐变的效果,最简单的是在两种颜色之间进行线性插值;可以使用
sqrt
等函数使效果启动更快
axvspan
可以在两个给定的 x 坐标之间绘制垂直跨度;设置 zorder=0
以确保跨度保持在直方图条的后面;或设置 alpha=0.3
将其绘制为横条上方的透明层
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
prices_np = 14*np.random.normal(5, 1, 10000)**2
left_border = 341.086
right_border = 437.177
# line_length = 1099
divisor_tickness = 10
main_color = mcolors.to_rgb('dodgerblue')
highlight_color = mcolors.to_rgb('limegreen')
divisor_color = mcolors.to_rgb('crimson')
binvals, bins, patches = plt.hist(prices_np, bins = 400, color=main_color)
bin_centers = 0.5 * (bins[:-1] + bins[1:])
for p, x in zip(patches, bin_centers):
#x, _ = p.get_xy()
#w = p.get_width()
if left_border < x < right_border:
f = 2*min(x-left_border, right_border-x) / (right_border - left_border)
f = f ** 0.5
p.set_facecolor([ (h_rgb*f + m_rgb * (1-f)) for m_rgb, h_rgb in zip(main_color, highlight_color)] )
elif left_border-divisor_tickness < x <= left_border or right_border <= x < right_border + divisor_tickness:
p.set_facecolor(divisor_color)
plt.axvspan(left_border, right_border, color='lightgoldenrodyellow', zorder=0)
plt.show()
要根据条形高度获得平滑的渐变,gaussian kde 可能很有用:
kde = gaussian_kde(prices_np)
max_kde = max([kde(x)[0] for x in bin_centers])
for x, p in zip(bin_centers, patches):
p.set_facecolor(plt.cm.viridis((kde(x)[0] / max_kde) ))
我有一个名为 prices
的数据,我使用 prices.tail(1)
构建直方图。
我还有一些变量:left_border = 341.086
、right_border = 437.177
、line_length = 1099
。
下一个代码:
plt.figure(figsize=(9,6))
plt.hist(prices.tail(1), bins = 400)
x2 = [left_border,left_border]
y2 = [0, line_length]
plt.plot(x2, y2, color = 'green')
x3 = [right_border, right_border]
y3 = [0, line_length]
plt.plot(x3, y3, color = 'green')
plt.show()
产生输出:
如何渐变地为绿色边界之间的直方图部分和绿色边界之外的部分着色?还要选择接近绿色边框的垃圾箱并将它们变成另一种颜色?
谢谢。
这里'gradiently'的确切含义我不清楚。这里有一些想法,可以作为创建所需解决方案的基础。
hist
returns 每个箱子的值,箱子的限制和绘制的补丁;你可以根据它们的平均 x 位置为补丁着色- 要创建类似渐变的效果,最简单的是在两种颜色之间进行线性插值;可以使用
sqrt
等函数使效果启动更快 axvspan
可以在两个给定的 x 坐标之间绘制垂直跨度;设置zorder=0
以确保跨度保持在直方图条的后面;或设置alpha=0.3
将其绘制为横条上方的透明层
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
prices_np = 14*np.random.normal(5, 1, 10000)**2
left_border = 341.086
right_border = 437.177
# line_length = 1099
divisor_tickness = 10
main_color = mcolors.to_rgb('dodgerblue')
highlight_color = mcolors.to_rgb('limegreen')
divisor_color = mcolors.to_rgb('crimson')
binvals, bins, patches = plt.hist(prices_np, bins = 400, color=main_color)
bin_centers = 0.5 * (bins[:-1] + bins[1:])
for p, x in zip(patches, bin_centers):
#x, _ = p.get_xy()
#w = p.get_width()
if left_border < x < right_border:
f = 2*min(x-left_border, right_border-x) / (right_border - left_border)
f = f ** 0.5
p.set_facecolor([ (h_rgb*f + m_rgb * (1-f)) for m_rgb, h_rgb in zip(main_color, highlight_color)] )
elif left_border-divisor_tickness < x <= left_border or right_border <= x < right_border + divisor_tickness:
p.set_facecolor(divisor_color)
plt.axvspan(left_border, right_border, color='lightgoldenrodyellow', zorder=0)
plt.show()
要根据条形高度获得平滑的渐变,gaussian kde 可能很有用:
kde = gaussian_kde(prices_np)
max_kde = max([kde(x)[0] for x in bin_centers])
for x, p in zip(bin_centers, patches):
p.set_facecolor(plt.cm.viridis((kde(x)[0] / max_kde) ))