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()
- Esta receta dibuja una anotación al seleccionar un punto de datos: http://scipy-cookbook.readthedocs.io/items/Matplotlib_Interactive_Plotting.html .
- Esta receta dibuja una información sobre herramientas, pero requiere wxPython: información sobre herramientas de puntos y líneas en matplotlib?
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