I wanted to read values off of the graphs that I made using python similar to how the data point values show up in an excel plot when you hover over a data point. Using various solutions here, I wrote up the below code to label the points as I hovered over them.
However, I can't seem to label some points when there are high y-axis values (that's my assumption on why it doesn't work), nor can I get the box to have a solid background so I can read the coordinates clearly (tried setting alpha to 1 but didn't work).Here's a picture of how one such point shows up far away from the actual location and with the text blocked by the curves behind it. Oddly enough, when all the y-axis values are below 1, the code worked fine.
from matplotlib import pyplot as plt
import numpy as np; np.random.seed(1)
x_data = list(range(0,30))
y1_data_a = np.sort(np.random.rand(30))
y1_data_b = np.sort(np.random.rand(30))
y1_data_c = [0.4 for point in x_data]
y2_data_a = [point**2 for point in x_data]
y2_data_b = [point*0.5 for point in y2_data_a]
y3_data = [(10/(point+1)) for point in x_data]
# #The code works fine with this data
# x_data = list(range(0,30))
# y1_data_a = np.sort(np.random.rand(30))
# y1_data_b = np.sort(np.random.rand(30))
# y1_data_c = [0.4 for point in x_data]
# y2_data_a = np.random.rand(30)
# y2_data_b = np.sort(np.random.rand(30))
# y3_data = np.sort(np.random.rand(30))[::-1]
fig, y1_axis = plt.subplots()
fig.subplots_adjust(right=0.75)
y2_axis = y1_axis.twinx()
y3_axis = y1_axis.twinx()
def make_patch_spines_invisible(ax):
ax.set_frame_on(True)
ax.patch.set_visible(False)
for sp in ax.spines.values():
sp.set_visible(False)
y3_axis.spines["right"].set_position(("axes", 1.2))
make_patch_spines_invisible(y3_axis)
y3_axis.spines["right"].set_visible(True)
plot1, = y1_axis.plot(x_data, y1_data_a, color="#000CFF", label="Temp1 (°C)")
plot2, = y1_axis.plot(x_data, y1_data_b, color="#FF5100", label="Temp2 (°C)")
plot3, = y1_axis.plot(x_data, y1_data_c, "r--", label="Critical Temp (°C)")
plot4, = y2_axis.plot(x_data, y2_data_a, color="#000000", label="Pressure1 (atm)")
plot5, = y2_axis.plot(x_data, y2_data_b, color="#17E111", label="Pressure2 (atm)")
plot6, = y3_axis.plot(x_data, y3_data, color="#D418DE", label="Volume (m3)")
y1_axis.set_xlabel("Time (hrs)")
y1_axis.set_ylabel("Temperature (°C)")
y2_axis.set_ylabel("Pressure (atm)")
y3_axis.set_ylabel("Volume (m3)")
y3_axis.yaxis.label.set_color(plot6.get_color())
tkw = dict(size=4, width=1.5)
y1_axis.tick_params(axis='y', **tkw)
y2_axis.tick_params(axis='y', **tkw)
y3_axis.tick_params(axis='y', colors=plot6.get_color(), **tkw)
y1_axis.tick_params(axis='x', **tkw)
lines = [plot1, plot2, plot4, plot5, plot6]
plt.title("Labeling data points for plots with Multiple Axes and Lines", fontdict=None, loc='center')
annot = y1_axis.annotate("", xy=(0, 0), xytext=(20, 20), textcoords="offset points",
bbox=dict(boxstyle="round", facecolor="#FFFFFF"),
arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)
def update_annot(line, annot, ind):
posx, posy = [line.get_xdata()[ind], line.get_ydata()[ind]]
annot.xy = (posx, posy)
text = f'{line.get_label()}: ({posx:.2f},{posy:.2f})'
annot.set_text(text)
annot.get_bbox_patch().set_alpha(1)
def hover(event):
vis = annot.get_visible()
if event.inaxes in [y1_axis, y2_axis, y3_axis]:
for line in lines:
cont, ind = line.contains(event)
if cont:
update_annot(line, annot, ind['ind'][0])
annot.set_visible(True)
fig.canvas.draw_idle()
else:
if vis:
annot.set_visible(False)
fig.canvas.draw_idle()
fig.canvas.mpl_connect("motion_notify_event", hover)
plt.show()
The ticker on the bottom right of the plot only seems to show the values based on the last axis that has been used. After searching here, I found 3 solutions that helps display a box containing the coordinates of a point:
- Possible to make labels appear when hovering over a point in matplotlib? (Didn't use this code exactly since it's for scatter plots but found other solutions from here)
- Annotate lines of a plot with matplotlib when hover with mouse [duplicate] (Used this to apply the previous solution to lines/curves)
- How to make labels appear when hovering over a point in multiple axis? (Used this to apply the labels to graphs with multiple axes)
How do I get the box to appear in graphs with high y-axis values and how do I make the box appear over the graphs so it can be read clearly? Thanks in advance!