tiempo real que matrices graficos graficas graficar ejes coordenadas python matplotlib

real - python graficos 2d



¿Es posible hacer que las etiquetas aparezcan al pasar el cursor sobre un punto en matplotlib? (6)

Desde http://matplotlib.sourceforge.net/examples/event_handling/pick_event_demo.html :

from matplotlib.pyplot import figure, show import numpy as npy from numpy.random import rand if 1: # picking on a scatter plot (matplotlib.collections.RegularPolyCollection) x, y, c, s = rand(4, 100) def onpick3(event): ind = event.ind print ''onpick3 scatter:'', ind, npy.take(x, ind), npy.take(y, ind) fig = figure() ax1 = fig.add_subplot(111) col = ax1.scatter(x, y, 100*s, c, picker=True) #fig.savefig(''pscoll.eps'') fig.canvas.mpl_connect(''pick_event'', onpick3) show()

Estoy usando matplotlib para hacer diagramas de dispersión. Cada punto en el gráfico de dispersión está asociado con un objeto nombrado. Me gustaría poder ver el nombre de un objeto cuando muevo el cursor sobre el punto en el gráfico de dispersión asociado con ese objeto. En particular, sería bueno poder ver rápidamente los nombres de los puntos que son atípicos. Lo más parecido que he podido encontrar durante la búsqueda aquí es el comando anotar, pero parece que crea una etiqueta fija en el diagrama. Desafortunadamente, con el número de puntos que tengo, el diagrama de dispersión sería ilegible si etiqueté cada punto. ¿Alguien sabe de una manera de crear etiquetas que solo aparecen cuando el cursor está cerca de ese punto?


Parece que ninguna de las otras respuestas aquí en realidad responde la pregunta. Entonces aquí hay un código que usa un scatter y muestra una anotación al pasar el mouse sobre los puntos de dispersión.

import matplotlib.pyplot as plt import numpy as np; np.random.seed(1) x = np.random.rand(15) y = np.random.rand(15) names = np.array(list("ABCDEFGHIJKLMNO")) c = np.random.randint(1,5,size=15) norm = plt.Normalize(1,4) cmap = plt.cm.RdYlGn fig,ax = plt.subplots() sc = plt.scatter(x,y,c=c, s=100, cmap=cmap, norm=norm) annot = ax.annotate("", xy=(0,0), xytext=(20,20),textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->")) annot.set_visible(False) def update_annot(ind): pos = sc.get_offsets()[ind["ind"][0]] annot.xy = pos text = "{}, {}".format(" ".join(list(map(str,ind["ind"]))), " ".join([names[n] for n in ind["ind"]])) annot.set_text(text) annot.get_bbox_patch().set_facecolor(cmap(norm(c[ind["ind"][0]]))) annot.get_bbox_patch().set_alpha(0.4) def hover(event): vis = annot.get_visible() if event.inaxes == ax: cont, ind = sc.contains(event) if cont: update_annot(ind) 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()

Debido a que las personas de repente también quieren usar esta solución para un plot líneas en lugar de una dispersión, la siguiente sería la misma solución para la plot (que funciona de forma ligeramente diferente).

import matplotlib.pyplot as plt import numpy as np; np.random.seed(1) x = np.sort(np.random.rand(15)) y = np.sort(np.random.rand(15)) names = np.array(list("ABCDEFGHIJKLMNO")) norm = plt.Normalize(1,4) cmap = plt.cm.RdYlGn fig,ax = plt.subplots() line, = plt.plot(x,y, marker="o") annot = ax.annotate("", xy=(0,0), xytext=(-20,20),textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->")) annot.set_visible(False) def update_annot(ind): x,y = line.get_data() annot.xy = (x[ind["ind"][0]], y[ind["ind"][0]]) text = "{}, {}".format(" ".join(list(map(str,ind["ind"]))), " ".join([names[n] for n in ind["ind"]])) annot.set_text(text) annot.get_bbox_patch().set_alpha(0.4) def hover(event): vis = annot.get_visible() if event.inaxes == ax: cont, ind = line.contains(event) if cont: update_annot(ind) 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()

En caso de que alguien esté buscando una solución para los gráficos de barras, consulte, por ejemplo, esta respuesta .


Sé que es una vieja pregunta, pero seguí llegando aquí mientras buscaba una solución para pasar (no hacer clic) una línea.

import matplotlib.pyplot as plt fig = plt.figure() plot = fig.add_subplot(111) # create some curves for i in range(4): plot.plot( [i*1,i*2,i*3,i*4], gid=i) def on_plot_hover(event): for curve in plot.get_lines(): if curve.contains(event)[0]: print "over %s" % curve.get_gid() fig.canvas.mpl_connect(''motion_notify_event'', on_plot_hover) plt.show()


Una pequeña edición en un ejemplo provisto en http://matplotlib.org/users/shell.html :

import numpy as np import matplotlib.pyplot as plt fig = plt.figure() ax = fig.add_subplot(111) ax.set_title(''click on points'') line, = ax.plot(np.random.rand(100), ''-'', picker=5) # 5 points tolerance def onpick(event): thisline = event.artist xdata = thisline.get_xdata() ydata = thisline.get_ydata() ind = event.ind print ''onpick points:'', zip(xdata[ind], ydata[ind]) fig.canvas.mpl_connect(''pick_event'', onpick) plt.show()

Esto traza un diagrama en línea recta, como Sohaib estaba preguntando


mplcursors funcionó para mí. mplcursors proporciona una anotación clicable para matplotlib. Está fuertemente inspirado en mpldatacursor ( https://github.com/joferkington/mpldatacursor ), con una API muy simplificada

import matplotlib.pyplot as plt import numpy as np import mplcursors data = np.outer(range(10), range(1, 5)) fig, ax = plt.subplots() lines = ax.plot(data) ax.set_title("Click somewhere on a line./nRight-click to deselect./n" "Annotations can be dragged.") mplcursors.cursor(lines) # or just mplcursors.cursor() plt.show()


mpld3 resolverlo por mí. EDITAR (CÓDIGO AGREGADO):

import matplotlib.pyplot as plt import numpy as np import mpld3 fig, ax = plt.subplots(subplot_kw=dict(axisbg=''#EEEEEE'')) N = 100 scatter = ax.scatter(np.random.normal(size=N), np.random.normal(size=N), c=np.random.random(size=N), s=1000 * np.random.random(size=N), alpha=0.3, cmap=plt.cm.jet) ax.grid(color=''white'', linestyle=''solid'') ax.set_title("Scatter Plot (with tooltips!)", size=20) labels = [''point {0}''.format(i + 1) for i in range(N)] tooltip = mpld3.plugins.PointLabelTooltip(scatter, labels=labels) mpld3.plugins.connect(fig, tooltip) mpld3.show()

Puedes verificar this ejemplo