En MATLAB, se puede usar datacursormode
para agregar anotaciones a un gráfico cuando el usuario pasa el mouse. ¿Hay tal cosa en matplotlib? ¿O necesito escribir mi propio evento usando matplotlib.text.Annotation
?¿Hay un matplotlib equivalente al modo de flujo de datos de MATLAB?
Respuesta
Edición tardía/Tapón desvergonzado: Esto ahora está disponible (con mucha más funcionalidad) como mpldatacursor
. Llamar al mpldatacursor.datacursor()
lo habilitará para todos los artistas matplotlib (incluyendo soporte básico para valores z en imágenes, etc.).
Por lo que yo sé, no lo es ya en marcha, pero no es demasiado difícil escribir algo similar:
import matplotlib.pyplot as plt
class DataCursor(object):
text_template = 'x: %0.2f\ny: %0.2f'
x, y = 0.0, 0.0
xoffset, yoffset = -20, 20
text_template = 'x: %0.2f\ny: %0.2f'
def __init__(self, ax):
self.ax = ax
self.annotation = ax.annotate(self.text_template,
xy=(self.x, self.y), xytext=(self.xoffset, self.yoffset),
textcoords='offset points', ha='right', va='bottom',
bbox=dict(boxstyle='round,pad=0.5', fc='yellow', alpha=0.5),
arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0')
)
self.annotation.set_visible(False)
def __call__(self, event):
self.event = event
# xdata, ydata = event.artist.get_data()
# self.x, self.y = xdata[event.ind], ydata[event.ind]
self.x, self.y = event.mouseevent.xdata, event.mouseevent.ydata
if self.x is not None:
self.annotation.xy = self.x, self.y
self.annotation.set_text(self.text_template % (self.x, self.y))
self.annotation.set_visible(True)
event.canvas.draw()
fig = plt.figure()
line, = plt.plot(range(10), 'ro-')
fig.canvas.mpl_connect('pick_event', DataCursor(plt.gca()))
line.set_picker(5) # Tolerance in points
Como parece que al menos una pocas personas están usando esto, he agregado una versión actualizada a continuación.
La nueva versión tiene un uso más simple y mucha más documentación (es decir, un poquito, al menos).
Básicamente debería usar este recurso similar a esto:
plt.figure()
plt.subplot(2,1,1)
line1, = plt.plot(range(10), 'ro-')
plt.subplot(2,1,2)
line2, = plt.plot(range(10), 'bo-')
DataCursor([line1, line2])
plt.show()
Las principales diferencias son que: a) no hay necesidad de llamar manualmente line.set_picker(...)
, b) no hay necesidad de llamar manualmente fig.canvas.mpl_connect
, yc) de este La versión maneja múltiples ejes y múltiples figuras.
from matplotlib import cbook
class DataCursor(object):
"""A simple data cursor widget that displays the x,y location of a
matplotlib artist when it is selected."""
def __init__(self, artists, tolerance=5, offsets=(-20, 20),
template='x: %0.2f\ny: %0.2f', display_all=False):
"""Create the data cursor and connect it to the relevant figure.
"artists" is the matplotlib artist or sequence of artists that will be
selected.
"tolerance" is the radius (in points) that the mouse click must be
within to select the artist.
"offsets" is a tuple of (x,y) offsets in points from the selected
point to the displayed annotation box
"template" is the format string to be used. Note: For compatibility
with older versions of python, this uses the old-style (%)
formatting specification.
"display_all" controls whether more than one annotation box will
be shown if there are multiple axes. Only one will be shown
per-axis, regardless.
"""
self.template = template
self.offsets = offsets
self.display_all = display_all
if not cbook.iterable(artists):
artists = [artists]
self.artists = artists
self.axes = tuple(set(art.axes for art in self.artists))
self.figures = tuple(set(ax.figure for ax in self.axes))
self.annotations = {}
for ax in self.axes:
self.annotations[ax] = self.annotate(ax)
for artist in self.artists:
artist.set_picker(tolerance)
for fig in self.figures:
fig.canvas.mpl_connect('pick_event', self)
def annotate(self, ax):
"""Draws and hides the annotation box for the given axis "ax"."""
annotation = ax.annotate(self.template, xy=(0, 0), ha='right',
xytext=self.offsets, textcoords='offset points', va='bottom',
bbox=dict(boxstyle='round,pad=0.5', fc='yellow', alpha=0.5),
arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0')
)
annotation.set_visible(False)
return annotation
def __call__(self, event):
"""Intended to be called through "mpl_connect"."""
# Rather than trying to interpolate, just display the clicked coords
# This will only be called if it's within "tolerance", anyway.
x, y = event.mouseevent.xdata, event.mouseevent.ydata
annotation = self.annotations[event.artist.axes]
if x is not None:
if not self.display_all:
# Hide any other annotation boxes...
for ann in self.annotations.values():
ann.set_visible(False)
# Update the annotation in the current axis..
annotation.xy = x, y
annotation.set_text(self.template % (x, y))
annotation.set_visible(True)
event.canvas.draw()
if __name__ == '__main__':
import matplotlib.pyplot as plt
plt.figure()
plt.subplot(2,1,1)
line1, = plt.plot(range(10), 'ro-')
plt.subplot(2,1,2)
line2, = plt.plot(range(10), 'bo-')
DataCursor([line1, line2])
plt.show()
- 1. ¿Hay una contraparte matplotlib de Matlab "stem3"?
- 2. Flujo de control de SSIS frente al flujo de datos
- 3. ¿Hay un operador de splat (o equivalente) en Matlab?
- 4. Modo interactivo en matplotlib
- 5. Convirtiendo Matlab en Octave ¿hay un contenedor.Mapa equivalente?
- 6. ¿Hay un equivalente a la función MATLAB bsxfun en python?
- 7. R equivalente al fmincon de MATLAB para la optimización restringida?
- 8. ¿Hay un equivalente SQLAlchemy de django-evolution?
- 9. ¿Hay un equivalente de Ruby al extracto de PHP?
- 10. ¿Hay un esquema equivalente al programa de ejecución de SBCL?
- 11. Matlab equivalente a la transmisión de Numpy?
- 12. Qt equivalente al enlace de datos .NET?
- 13. ¿Hay alguna manera de generar automáticamente diagramas de flujo de datos y diagramas de flujo?
- 14. ¿hay un Java equivalente al "algo" de JavaScript?
- 15. ¿Hay un equivalente al Proceso de C#. Comienza en PHP?
- 16. ¿Hay un C++ equivalente al BigDecimal de Java?
- 17. ¿Hay un python equivalente al comando `which` de Unix?
- 18. ¿Hay un python equivalente al módulo arrancador de perl?
- 19. ¿Hay un equivalente al urllib de python en c/C++?
- 20. ¿Hay un JUnit equivalente al atributo testcase de NUnit?
- 21. ¿Hay un C# equivalente al repetidor de salida STL?
- 22. ¿Hay un MSTest equivalente al atributo explícito de NUnit?
- 23. ¿Hay un Vim equivalente al comando "fold" de Linux/Unix?
- 24. Suavizado de curva simple en matplotlib --- ¿equivalente al "bezier liso" de gnuplot?
- 25. ¿Hay un equivalente en Python de la función conv2 de MATLAB?
- 26. ¿Hay un equivalente de C# de m_nCmdShow?
- 27. Equivalente de Matlab 'ismember' en numpy (Python)?
- 28. MATLAB equivalente a string.join de Python()
- 29. ¿Hay un equivalente binario de System.Text.StringBuilder?
- 30. ¿Hay un equivalente de Profiler para MySql?
Esto es genial. ¡Gracias! – unutbu
Joe, comenté 'xdata, ydata = event.artist.get_data()' porque no parece ser usado, y planteé una [pregunta] (http://stackoverflow.com/q/8956794/190597) . Espero que esté bien. – unutbu
¡Absolutamente, gracias! No debería haberlo dejado allí. Además, probablemente debería actualizar esto ... Tendría más sentido pasar a un artista en particular que a un eje. –