Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to refresh text in Matplotlib?

I wrote this code to read data from an excel file and to plot them. For a certain x-value, I desire to know the y-values of all the lines so I create a slider to change this x-value but I'm not able to refresh the text which prints the y-value.

The code is this

import numpy as np
from openpyxl import load_workbook as ld
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider

wb = ld(filename='example.xlsx')
data = wb['data']
time = wb['time']
row = data.max_row
column = data.max_column
x = np.ones((row, column))
y = np.ones((row, column))
result = np.ones(row)
for i in range(0, row):
    for j in range(0, column):

        x[i][j] = time.cell(row=i+1, column=j+1).value
        y[i][j] = data.cell(row=i+1, column=j+1).value


fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
plt.plot(x[0], y[0], label='line1')
plt.plot(x[1], y[1], label='line2')
plt.plot(x[2], y[2], label='line3')
line, = plt.plot((np.amin(x), np.amin(x)), (np.amin(y), np.amax(y)))
plt.legend()
plt.grid(True)


axtime = plt.axes([0.25, 0.1, 0.65, 0.03])
stime = Slider(axtime, 'time', np.amin(x), np.amax(x), valinit=np.amin(x))


def y_text(r):
    ax.text(10, 8, str(r), style='italic')


def find(t):
    global x, y, result

    for i in range(0, row):
        for j in range(0, column):

            if x[i][j] == t or (t < x[i][j] and j == 0) or (t > x[i][j] and j == column):
                result[i] = y[i][j]
            elif x[i][j] < t < x[i][j+1]:
                result[i] = ((t-x[i][j])/(x[i][j+1]-x[i][j]))*(y[i][j+1]-y[i][j])+y[i][j]
    return result


def update(val):
    line.set_xdata(stime.val)
    find(stime.val)
    y_text(stime.val)
    fig.canvas.draw()
stime.on_changed(update)


plt.show()

and the result is this

enter image description here

As you can see the text is overwritten.

like image 370
Leo Avatar asked Aug 30 '16 09:08

Leo


People also ask

What is Matplotlib BBOX?

BboxTransformTo is a transformation that linearly transforms points from the unit bounding box to a given Bbox. In your case, the transform itself is based upon a TransformedBBox which again has a Bbox upon which it is based and a transform - for this nested instance an Affine2D transform.


1 Answers

With matplotlib widgets, the update method works best if you create an artist object and adjust its value (like you do with line in your code). For a text object, you can use the set_text and set_position method to change what it displays and where. As an example,

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

fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.25)
sax = plt.axes([0.25, 0.1, 0.65, 0.03])

x = np.linspace(0,2.*np.pi,100)
f = np.sin(x)
l, = ax.plot(x, f)

slider1 = Slider(sax, 'amplitude', -0.8, 0.8, valinit=0.8)

tpos = int(0.25*x.shape[0])
t1 = ax.text(x[tpos], f[tpos],  str(slider1.val))

tpos = int(0.75*x.shape[0])
t2 = ax.text(x[tpos], f[tpos],  str(slider1.val))

def update(val):
    f = slider1.val*np.sin(x)
    l.set_ydata(f)

    # update the value of the Text object
    tpos = int(0.25*x.shape[0])
    t1.set_position((x[tpos], f[tpos]))
    t1.set_text(str(slider1.val))

    tpos = int(0.75*x.shape[0])
    t2.set_position((x[tpos], f[tpos]))
    t2.set_text(str(slider1.val))

    plt.draw()

slider1.on_changed(update)
plt.show()

which looks like,

enter image description here

The alternative may be to clear and redraw the text each time but this is slower and will be more hassle.

like image 62
Ed Smith Avatar answered Oct 18 '22 02:10

Ed Smith