1

I want my figure to have a small entry window, in which the user can type a number, and the data plotted will span that many minutes. If they enter 30, they will look at a 30-minute time window, if they type 5, matplotlib picks this up, data gets trimmed, and only 5 minutes worth of data gets shown.

How can I do this? I noticed that people on SO recommend using TkAgg, is there a way to do this without it? If I do use TkAgg, can you point me to a minimal example that does this in an interactive manner, i.e. picks up new entries that the user makes?

Thank you

EDIT: This is STREAMING data, so I want to condition to be of dynamic form, such as 'give me last 15 minutes' rather than 'give me between 2:10 and 2:25'. Also, I will performing the trimming of the data manually myself, the gui doesn't have to do it. The gui only needs to read a single number and make it available to me.

ONE MORE DETAIL: Don't worry about what happens behind the curtains, I know how to take care of it. All I want to know is simply how to read a number from a text box on a figure in matplotlib.

3
  • Does it have to be a text box or would a slider work just as well? Commented Aug 22, 2014 at 14:39
  • Any, whichever is easier, but I did assume text box would be simpler, and consume less resources? In any case, whichever is simple, perhaps it would be good to see example of both? Commented Aug 22, 2014 at 14:53
  • Matplotlib will soon introduce a TextBox Widget (probably in version 2.1(?)). See it's usage in this example. Commented Jun 23, 2017 at 12:11

1 Answer 1

1

I don't think you can do what you want using a text box without using a 3rd party GUI program. The example below shows how a slider can be used to change the x limits of a plot using just matplotlib itself.

The example used a Slider widget to control the xlimits. You can find another example of using many widgets here.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider

# Create some random data
x = np.linspace(0,100,1000)
y = np.sin(x) * np.cos(x)

left, bottom, width, height = 0.15, 0.02, 0.7, 0.10

fig, ax = plt.subplots()

plt.subplots_adjust(left=left, bottom=0.25) # Make space for the slider

ax.plot(x,y)

# Set the starting x limits
xlims = [0, 1]
ax.set_xlim(*xlims)

# Create a plt.axes object to hold the slider
slider_ax = plt.axes([left, bottom, width, height])
# Add a slider to the plt.axes object
slider = Slider(slider_ax, 'x-limits', valmin=0.0, valmax=100.0, valinit=xlims[1])

# Define a function to run whenever the slider changes its value.
def update(val):
    xlims[1] = val
    ax.set_xlim(*xlims)

    fig.canvas.draw_idle()

# Register the function update to run when the slider changes value
slider.on_changed(update)

plt.show()

Below are some plots showing the slider at different positions:

Default (starting) position

fig 1

Setting the slider to a random value

fig 2

Setting the slider to the maximum value

fig 3

Sign up to request clarification or add additional context in comments.

7 Comments

This is useful, but not exactly what I want, that's why I did not immediately accept it. This is streaming data, so I want the x-axis interval to be of the form 'give me last 30 mins' rather than 'give me between 3:20 a.m. and 3:50 a.m.' Can you perhaps elaborate a little bit on the third party tools? Maybe TkAgg?
Also, I have many charts on one single, compact figure. How can I do it so that I have only one, global slider that applies to all of them?
Ok it sounds like you're going to need something a lot more complicated. In this case your best bet is to write your own custom GUI using something like Tkinter, wxPython or PyQT. You can embed matplotlib graphs inside these GUIs (two examples for Tkinter are here and here). Unfortunately I don't have any experience doing this so won't be able to help. I'd suggest you update your question with more details so people can make a working example though.
I will take care of the backend myself(trimming the data). I would like to simply read a single number, the number of minutes, all else I will do myself, and will pass trimmed, formatted data to matplotlib.
Ok in that case your best bet is to write a simply GUI that accepts an argument (minutes) via a text box. Say you've plotted your data with line, = ax.plot(x, y) then you can do line.set_data to update the data that is contained within line.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.