如何在鼠标移动时动态改变图形的颜色?
How to dynamically change color of a graph on mouse movement?
我有一个条形图。我希望它在我上下移动光标时改变颜色(因此基于 y 值)。我现在可以制作一个离散的颜色值列表并在每次点击时更新图表。但我仍然不知道如何让它连续不断地运动。
import matplotlib.pyplot as plt
from math import floor
def hex_to_RGB(hex):
# Pass 16 to the integer function for change of base
return [int(hex[i:i + 2], 16) for i in range(1, 6, 2)]
def RGB_to_hex(RGB):
# Components need to be integers for hex to make sense
RGB = [int(x) for x in RGB]
return "#" + "".join(["0{0:x}".format(v) if v < 16 else
"{0:x}".format(v) for v in RGB])
def color_dict(gradient):
return {"hex": [RGB_to_hex(RGB) for RGB in gradient],
"r": [RGB[0] for RGB in gradient],
"g": [RGB[1] for RGB in gradient],
"b": [RGB[2] for RGB in gradient]}
def linear_gradient(start_hex, finish_hex="#FFFFFF", n = 100):
# Starting and ending colors in RGB form
s = hex_to_RGB(start_hex)
f = hex_to_RGB(finish_hex)
# Initilize a list of the output colors with the starting color
RGB_list = [s]
# Calcuate a color at each evenly spaced value of t from 1 to n
for t in range(1, n):
# Interpolate RGB vector for color at the current value of t
curr_vector = [
int(s[j] + (float(t) / (n - 1)) * (f[j] - s[j]))
for j in range(3)]
# Add it to our list of output colors
RGB_list.append(curr_vector)
return color_dict(RGB_list)
WtoR = linear_gradient('#FFFFFF', '#FF0000')['hex']
# -------------------------------- PLOTTING -----------------------------------------
width = 1
plt.figure()
plt.bar(1, 100, width, color = 'white', align = 'center')
def onclick(event):
plt.cla()
plt.clf()
y = event.ydata
plt.bar(1, 100, width, color = str(WtoR[floor(y)]), align = 'center')
plt.draw()
plt.gcf().canvas.mpl_connect('button_press_event', onclick)
plt.show()
TL/DR;将您的点击代码更改为:
def onmotion(event):
plt.cla()
plt.clf()
plt.gca()
y = event.ydata
if y:
plt.bar(1, 100, width, color = str(WtoR[int(y)]), align = 'center')
plt.draw()
plt.gcf().canvas.mpl_connect('motion_notify_event', onmotion)
您已经注册了您的 onclick 函数,以便在您收到按钮按下事件时调用。要在鼠标移动时立即更新,您应该收听动作通知事件。
但是,对于这个事件,你不一定能得到一个 y 值(如果你不在图中的轴内),因此只有当你有一个 y 值时,你才必须有条件地更新。
此外,当离开 window 时,matplotlib 的坐标轴似乎已停用。这意味着它们必须通过 plt.gca() 调用重新激活。
请注意,对我来说,在 python 2.7 中无法使用 floor() 函数的值对数组进行索引。我不得不改用 int() ,但这在 python 3.
中可能会有所不同
此外,现在每次调用回调时都会重新绘制条形图。可能值得研究获取第一个条形图的 id 然后仅更新颜色的可能性。这可能会更快,因为它可能需要更少的计算机。
我有一个条形图。我希望它在我上下移动光标时改变颜色(因此基于 y 值)。我现在可以制作一个离散的颜色值列表并在每次点击时更新图表。但我仍然不知道如何让它连续不断地运动。
import matplotlib.pyplot as plt
from math import floor
def hex_to_RGB(hex):
# Pass 16 to the integer function for change of base
return [int(hex[i:i + 2], 16) for i in range(1, 6, 2)]
def RGB_to_hex(RGB):
# Components need to be integers for hex to make sense
RGB = [int(x) for x in RGB]
return "#" + "".join(["0{0:x}".format(v) if v < 16 else
"{0:x}".format(v) for v in RGB])
def color_dict(gradient):
return {"hex": [RGB_to_hex(RGB) for RGB in gradient],
"r": [RGB[0] for RGB in gradient],
"g": [RGB[1] for RGB in gradient],
"b": [RGB[2] for RGB in gradient]}
def linear_gradient(start_hex, finish_hex="#FFFFFF", n = 100):
# Starting and ending colors in RGB form
s = hex_to_RGB(start_hex)
f = hex_to_RGB(finish_hex)
# Initilize a list of the output colors with the starting color
RGB_list = [s]
# Calcuate a color at each evenly spaced value of t from 1 to n
for t in range(1, n):
# Interpolate RGB vector for color at the current value of t
curr_vector = [
int(s[j] + (float(t) / (n - 1)) * (f[j] - s[j]))
for j in range(3)]
# Add it to our list of output colors
RGB_list.append(curr_vector)
return color_dict(RGB_list)
WtoR = linear_gradient('#FFFFFF', '#FF0000')['hex']
# -------------------------------- PLOTTING -----------------------------------------
width = 1
plt.figure()
plt.bar(1, 100, width, color = 'white', align = 'center')
def onclick(event):
plt.cla()
plt.clf()
y = event.ydata
plt.bar(1, 100, width, color = str(WtoR[floor(y)]), align = 'center')
plt.draw()
plt.gcf().canvas.mpl_connect('button_press_event', onclick)
plt.show()
TL/DR;将您的点击代码更改为:
def onmotion(event):
plt.cla()
plt.clf()
plt.gca()
y = event.ydata
if y:
plt.bar(1, 100, width, color = str(WtoR[int(y)]), align = 'center')
plt.draw()
plt.gcf().canvas.mpl_connect('motion_notify_event', onmotion)
您已经注册了您的 onclick 函数,以便在您收到按钮按下事件时调用。要在鼠标移动时立即更新,您应该收听动作通知事件。
但是,对于这个事件,你不一定能得到一个 y 值(如果你不在图中的轴内),因此只有当你有一个 y 值时,你才必须有条件地更新。
此外,当离开 window 时,matplotlib 的坐标轴似乎已停用。这意味着它们必须通过 plt.gca() 调用重新激活。
请注意,对我来说,在 python 2.7 中无法使用 floor() 函数的值对数组进行索引。我不得不改用 int() ,但这在 python 3.
中可能会有所不同此外,现在每次调用回调时都会重新绘制条形图。可能值得研究获取第一个条形图的 id 然后仅更新颜色的可能性。这可能会更快,因为它可能需要更少的计算机。