python - Python:如何在对数空间中的两条曲线之间绘制等距曲线?
问题描述
这是@JohanC 回答的以下链接的后续问题。
归功于(https://stackoverflow.com/users/12046409/johanc):
如何在红色和蓝色曲线之间绘制一条与两者等距的曲线?我尝试即兴编写代码,但由于日志空间,绿色曲线偏向红色曲线。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from scipy import interpolate
xmin, xmax = 2000, 7000
ymin, ymax = 10, 50000
# a grid of 6 x,y coordinates for both curves
x_grid = np.array([2000, 3000, 4000, 5000, 6000, 7000])
y_blue_grid = np.array([15, 100, 200, 300, 400, 500])
y_red_grid = np.array([20, 400, 10000, 500000, 500000, 500000])
y_avg_grid = np.array([17.5, 250, 5100, 250150, 250200, 250250])
# create interpolating curves in logspace
tck_red = interpolate.splrep(x_grid, np.log(y_red_grid), s=0)
tck_blue = interpolate.splrep(x_grid, np.log(y_blue_grid), s=0)
tck_avg = interpolate.splrep(x_grid, np.log(y_avg_grid), s=0)
x = np.linspace(xmin, xmax)
yr = np.exp(interpolate.splev(x, tck_red, der=0))
yb = np.exp(interpolate.splev(x, tck_blue, der=0))
yavg = np.exp(interpolate.splev(x, tck_avg, der=0))
# create the background image; it is created fully in logspace
# the background (z) is zero between the curves, negative in the blue zone and positive in the red zone
# the values are close to zero near the curves, gradually increasing when they are further
xbg = np.linspace(xmin, xmax, 50)
ybg = np.linspace(np.log(ymin), np.log(ymax), 50)
z = np.zeros((len(ybg), len(xbg)), dtype=float)
for i, xi in enumerate(xbg):
yi_r = interpolate.splev(xi, tck_red, der=0)
yi_b = interpolate.splev(xi, tck_blue, der=0)
# yi_avg = interpolate.splev(xi, tck_avg, der=0)
for j, yj in enumerate(ybg):
if yi_b >= yj:
z[j][i] = (yj - yi_b)
elif yi_r <= yj:
z[j][i] = (yj - yi_r)
fig, ax2 = plt.subplots(figsize=(8, 8))
# draw the background image, set vmax and vmin to get the desired range of colors;
# vmin should be -vmax to get the white at zero
ax2.imshow(z, origin='lower', extent=[xmin, xmax, np.log(ymin), np.log(ymax)], aspect='auto', cmap='bwr', vmin=-12, vmax=12, interpolation='bilinear', zorder=-2)
ax2.set_ylim(ymin=np.log(ymin), ymax=np.log(ymax)) # the image fills the complete background
ax2.set_yticks([]) # remove the y ticks of the background image, they are confusing
ax = ax2.twinx() # draw the main plot using the twin y-axis
ax.set_yscale('log')
ax.plot(x, yr, label="Warm", color='crimson')
ax.plot(x, yb, label="Blue", color='dodgerblue')
ax.plot(x, yavg, label="Comfort", color='green')
ax2.set_xlabel('Color Temperature (K)')
ax.set_ylabel('Illuminance (lux)')
ax.set_title('Kruithof Curve',fontsize=16)
ax.legend()
ax.set_xlim(xmin=xmin, xmax=xmax)
ax.set_ylim(ymin=ymin, ymax=ymax)
ax.grid(True, which='major', axis='y')
ax.grid(True, which='minor', axis='y', ls=':')
ax.yaxis.tick_left() # switch the twin axis to the left
ax.yaxis.set_label_position('left')
ax2.grid(True, which='major', axis='x')
ax2.xaxis.set_major_formatter(mticker.StrMethodFormatter('{x:.0f}')) # show x-axis in Kelvin
ax.text(5000, 2000, 'Pleasing', fontsize=16)
ax.text(5000, 20, 'Appears bluish', fontsize=16)
ax.text(2300, 15000, 'Appears reddish', fontsize=16)
plt.show()
输出:
所需的输出如下,即得到一条黄线。黄线不仅用于图形目的,而且我还需要这些值以供进一步使用。
谢谢你。
解决方案
推荐阅读
- python - 在 Kivy 上安装和使用 matplotlib
- mysql - MySQL查询以获取用户未关注的帖子列表
- html - 如何让我的输入标签在调整大小时向下移动?
- java - Java:Javax Cipher 类中默认设置哪种模式?
- ios - UICollectionView 在 ScrollView 内不滚动(水平)
- javascript - 为什么我的输入框在用户输入方面表现得很奇怪?
- c# - Ext.NET HyperlinkColumn 不显示
- sql-server - while循环问题,从期间计算天数
- python - 从 docx 文件中删除字符
- authentication - 如何读取登录时间 - 更改座位位置的通知