4

I have a problem with plotting in matplotlib. I need to plot a wide figure which represents an allocation of radio resources in time. But when a time period is big, the plot shrinks and I need to zoom it to see what is in particular fragment. What I want, is to plot the data without scaling ("real size") and to use the scrollbars to scroll the plot horizontally (in time). Is that possible?

3
  • 1
    You may produce an image of your plot of arbitrary size and then use your favorite program to view it. I don't think any of the matplotlib backends supports scrollbars -- of course, you may just zoom in and use the hand tool to scroll... Commented Feb 13, 2012 at 10:58
  • 1
    Okay, so I assume, that I need to use: fig.set_size_inches(XX,YY) fig.savefig('filename') And that seems to work, but is there any way to set the saved figure size as 1:1 size? Because it can be difficult to determine which size should I use for the next plot, and I will need to chenge script every time (or pass additional arg)? Commented Feb 13, 2012 at 11:14
  • 1
    What do you mean by 1:1 size? What units are you using to specify your plot? And how shall those units relate to the pixels displayed by your screen? Commented Feb 13, 2012 at 12:00

1 Answer 1

4

Here's an example from a scipy cookbook:

When plotting a very long sequence in a matplotlib canvas embedded in a wxPython application, it sometimes is useful to be able to display a portion of the sequence without resorting to a scrollable window so that both axes remain visible. Here is how to do so:

from numpy import arange, sin, pi, float, size

import matplotlib
matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
from matplotlib.figure import Figure

import wx

class MyFrame(wx.Frame):
    def __init__(self, parent, id):
        wx.Frame.__init__(self,parent, id, 'scrollable plot',
                style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER,
                size=(800, 400))
        self.panel = wx.Panel(self, -1)

        self.fig = Figure((5, 4), 75)
        self.canvas = FigureCanvasWxAgg(self.panel, -1, self.fig)
        self.scroll_range = 400
        self.canvas.SetScrollbar(wx.HORIZONTAL, 0, 5,
                                 self.scroll_range)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas, -1, wx.EXPAND)

        self.panel.SetSizer(sizer)
        self.panel.Fit()

        self.init_data()
        self.init_plot()

        self.canvas.Bind(wx.EVT_SCROLLWIN, self.OnScrollEvt)

    def init_data(self):

        # Generate some data to plot:
        self.dt = 0.01
        self.t = arange(0,5,self.dt)
        self.x = sin(2*pi*self.t)

        # Extents of data sequence: 
        self.i_min = 0
        self.i_max = len(self.t)

        # Size of plot window:       
        self.i_window = 100

        # Indices of data interval to be plotted:
        self.i_start = 0
        self.i_end = self.i_start + self.i_window

    def init_plot(self):
        self.axes = self.fig.add_subplot(111)
        self.plot_data = \
                  self.axes.plot(self.t[self.i_start:self.i_end],
                                 self.x[self.i_start:self.i_end])[0]

    def draw_plot(self):

        # Update data in plot:
        self.plot_data.set_xdata(self.t[self.i_start:self.i_end])
        self.plot_data.set_ydata(self.x[self.i_start:self.i_end])

        # Adjust plot limits:
        self.axes.set_xlim((min(self.t[self.i_start:self.i_end]),
                           max(self.t[self.i_start:self.i_end])))
        self.axes.set_ylim((min(self.x[self.i_start:self.i_end]),
                            max(self.x[self.i_start:self.i_end])))

        # Redraw:                  
        self.canvas.draw()

    def OnScrollEvt(self, event):

     # Update the indices of the plot:
        self.i_start = self.i_min + event.GetPosition()
        self.i_end = self.i_min + self.i_window + event.GetPosition()
        self.draw_plot()

class MyApp(wx.App):
    def OnInit(self):
        self.frame = MyFrame(parent=None,id=-1)
        self.frame.Show()
        self.SetTopWindow(self.frame)
        return True

if __name__ == '__main__':
    app = MyApp()
    app.MainLoop()
  • The example needs wxPython, numpy and matplotlib; pip install numpy matplotlib wxPython to install them.

Source: https://scipy-cookbook.readthedocs.io/items/Matplotlib_ScrollingPlot.html

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

6 Comments

Can you give more detail than a link?
I agree, your answer is spot on... I guess I was looking for a quick summary of how it does it, in case the scipy site was down. But looking at the code, it seems like saying more than "using a wxPython application" would involve a word for word explaining what the code does. +1 for the right answer, I was just sharing my impressions of the answer.
OK, you're right in that it's worth saying a couple of words rather than just a link. An explanation of what a code does is indeed not worth it, but a one-sentence preamble is.
Hi! Sorry for my long absence. But now I'm back ;) This link is exactly what I was looking for, but still do not cover all of my needs... but this is a topic for later. I have tried to combine this code, with my plotting code - see edited question.
the link doesn't work. They seemed to have removed the scrolling plot example. I searched the cookbook and nothing came up. Do you know any other sources for this problem ? Please help.
|

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.