0

Most relevant questions I've seen here are not fixing my issue. I'm writing a program that uses matplotlib and tkinter to make a GUI. I'm running CentOS7. I get this when trying to run python36 testGraph.pyon my server:

Traceback (most recent call last):
  File "testGraph.py", line 167, in <module>
    app = SeaofBTCapp()
  File "testGraph.py", line 57, in __init__
    tk.Tk.__init__(self, *args, **kwargs)
  File "/usr/lib64/python3.6/tkinter/__init__.py", line 2020, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

I'm not sure what to try next. The file is below. Lots of people said just moving the import statement for matplotlib to the top of the file fixed their issue. It didn't for mine.

import matplotlib
matplotlib.use("TkAgg")
import tkinter as tk
from tkinter import ttk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib import style
style.use("ggplot")

# Function to get CPU frequency
def getfreq():

    with open('/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq', 'r') as f:

        for line in f.readlines():

            lineSplit = line.split(':')

            if len(lineSplit) == 2:

                lineSplit[0] = lineSplit[0].strip()
                lineSplit[1] = lineSplit[1].strip()

                if lineSplit[0] == "cpu MHz":
                    frequency = float(lineSplit[1])
                    return frequency


# Data fields needed for plotting live data
time = 0
xs = []
ys = []

f = Figure(figsize = (5, 5), dpi = 100)
a = f.add_subplot(111)

# Animation function to update plot
def animate(i):
    global time

    frequency = getfreq()

    xs.append(float(time))
    time = time + 1
    ys.append(frequency)
    a.clear()
    a.plot(xs, ys)


class SeaofBTCapp(tk.Tk):

    def __init__(self, *args, **kwargs):

        # Initialize Tkinter

        tk.Tk.__init__(self, *args, **kwargs)

        tk.Tk.wm_title(self, "CPU Frequency and Power Plot")

        container = tk.Frame(self)

        container.pack(side = "top", fill = "both", expand = True)

        container.grid_rowconfigure( 0, weight = 1)
        container.grid_columnconfigure(0, weight = 1)

        self.frames = {}

        for F in (StartPage, PageOne, PageTwo, PageThree):

            frame = F(container, self)

            self.frames[F] = frame

            frame.grid(row = 0, column = 0, sticky = "nsew")

        self.show_frame(StartPage)


    def show_frame(self, cont):

        frame = self.frames[cont]

        frame.tkraise()


class StartPage(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)

        label = tk.Label(self, text = "hello world")

        label.pack()

        button1 = ttk.Button(self, text = "Visit Page 1", command = lambda: controller.show_frame(PageOne))

        button1.pack()

        button2 = ttk.Button(self, text = "Visit Page 2", command = lambda: controller.show_frame(PageTwo))

        button2.pack()

        button3 = ttk.Button(self, text="Visit Graph Page", command=lambda: controller.show_frame(PageThree))

        button3.pack()

class PageOne(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)

        label = ttk.Label(self, text="Page 1!")

        label.pack()

        button1 = ttk.Button(self, text="Visit Home Page", command= lambda: controller.show_frame(StartPage))

        button1.pack()

class PageTwo(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)

        label = ttk.Label(self, text="Page 2!")

        label.pack()

        button1 = ttk.Button(self, text="Visit Home Page", command= lambda: controller.show_frame(StartPage))

        button1.pack()

# Frequency Graph Page
class PageThree(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)

        label = ttk.Label(self, text="Graph Page!")

        label.pack()

        button1 = ttk.Button(self, text="Visit Home Page", command= lambda: controller.show_frame(StartPage))

        button1.pack()

        canvas = FigureCanvasTkAgg(f, self)

        canvas.draw()

        canvas.get_tk_widget().pack(side = tk.TOP, fill = tk.BOTH, expand = True)

        toolbar = NavigationToolbar2Tk(canvas, self)

        toolbar.update()

        canvas._tkcanvas.pack(side = tk.TOP, fill = tk.BOTH, expand = True)



app = SeaofBTCapp()

ani = animation.FuncAnimation(f, animate, interval = 1000)

app.mainloop()
Mr.Mips
  • 379
  • 2
  • 18
  • *"no $DISPLAY environment variable"*: Look like a `CentOS7` issue. Does a simple `root = tk.Tk()` work at least? – stovfl Jan 23 '19 at 08:31
  • Just to eliminate all possibilities: If you run this on your server, do you `ssh` with the `-X` flag? – Thomas Kühn Jan 23 '19 at 10:37
  • @ThomasKühn I do not ssh with the -X flag. – Mr.Mips Jan 23 '19 at 23:05
  • @stovfl No. It does not. After running `import tkinter as tk` and `from tkinter import tkk` in my python36 shell, running `root = tk.Tk()` throws the same error. – Mr.Mips Jan 23 '19 at 23:09
  • 1
    Please have a look at [this](https://unix.stackexchange.com/q/12755/154741). – Thomas Kühn Jan 24 '19 at 04:39
  • Relevant [“No X11 DISPLAY variable” - what does it mean?](https://stackoverflow.com/a/662429/7414759) and [Linux: where are environment variables stored?](https://stackoverflow.com/questions/532155/linux-where-are-environment-variables-stored) – stovfl Jan 24 '19 at 08:36
  • 1
    @ThomasKühn this was the issue. I had X forwarding enabled on the client side, but not the server side. – Mr.Mips Jan 24 '19 at 22:13

0 Answers0