我有一个条形图。我希望它能在我上下移动光标时改变颜色(所以基于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()
答案 0 :(得分:1)
TL/DR; change your onclick code to:
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)
You have registered your onclick function to be called whenever you get receive a button press event. To have it update as soon as the mouse is moved you should listen to the motion notify event.
However, with this event, you are not certain to get a y value (if you are not within the axes of the figure), therefore you have to update only conditionally when you have a y value.
Further, when leaving the window, it seems the axes are deactivated to matplotlib. This means that they have to be reactivated by a plt.gca() call.
And as a note, for me in python 2.7 it did not work to index the array with the value from the floor() function. I had to use int() instead, but this may work differently in python 3.
Also, right now, the bar plot is redrawn every time the callback is called. It might be worthwhile looking into the possibility to get the id the of the first bar and then update the color only. This could be quicker, as it may require less from the computer.