python + tkinter + matplotlib – Axes labels not displaying

Question:

Edited to include example code and image.

I am trying to embed a matplotlib figure on a tkinter GUI. I am able to see the plot, but the axes labels are not displaying as I would hope. Here is the code I’m using to add the plots:

import os
import tkinter as tk
from tkinter import ttk

import matplotlib
from matplotlib import pyplot as plt
from matplotlib.axes import Axes
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg


if os.environ.get("DISPLAY") is not None:
    matplotlib.use("TkAgg")


class MyGUI(ttk.Frame):
    def __init__(self, parent):
        ttk.Frame.__init__(self)

        x_data = [0, 0.5, 1, 1.5, 2, 2.5, 3]
        y_data = [0, 0.25, 1, 2.25, 4, 6.25, 9]

        self.report_frame = ttk.Frame(self, padding=(20, 10))
        self.report_frame.pack(expand=1, fill="both")
        fig1 = plt.figure(figsize=(3.5, 3), dpi=100)
        ax1: Axes = fig1.add_subplot(111)
        ax1.plot(x_data, y_data, "b-")
        ax1.set_title("Plot Title")
        ax1.set_xlabel("X axis Label")
        ax1.set_xlim([0, 3])
        ax1.set_ylabel("Y axis Label")
        ax1.set_ylim([0, 9])

        fig1_canvas = FigureCanvasTkAgg(fig1, self.report_frame)
        fig1_canvas.get_tk_widget().grid(row=0, column=0, sticky="nw")


if __name__ == "__main__":
    root = tk.Tk()
    root.title("Plot Test")

    app = MyGUI(root)
    app.pack()
    root.mainloop()

The resulting image looks like this:

Example image

The Y-axis label is visible here, but the X-axis label is cut off. I’m trying to figure out the syntax to adjust the view so that the entire figure including labels is visible in the Frame.

Asked By: Jacob F.

||

Answers:

I found that adding constrained_layout=True to the figure creation worked for my purpose.

fig1 = plt.figure(figsize=(3.5, 3), dpi=100, constrained_layout=True)

I am still interested in other methods for adjusting the figure view.
enter image description here

Answered By: Jacob F.

I like your answer as it is simple and does what you need. If you want further control (on every aspect of the figure) you can use plt.subplots_adjust link and change whatever you need to until you get the desired results:

import os
import tkinter as tk
from tkinter import ttk

import matplotlib
from matplotlib import pyplot as plt
from matplotlib.axes import Axes
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg


if os.environ.get("DISPLAY") is not None:
    matplotlib.use("TkAgg")


class MyGUI(ttk.Frame):
    def __init__(self, parent):
        ttk.Frame.__init__(self)

        x_data = [0, 0.5, 1, 1.5, 2, 2.5, 3]
        y_data = [0, 0.25, 1, 2.25, 4, 6.25, 9]

        self.report_frame = ttk.Frame(self, padding=(20, 10))
        self.report_frame.pack(expand=1, fill="both")
        fig1 = plt.figure(figsize=(3.5, 3), dpi=100)
        #fig1 = plt.figure(figsize=(3.5, 3), dpi=100, constrained_layout=True)
        ax1: Axes = fig1.add_subplot(111)
        ax1.plot(x_data, y_data, "b-")
        ax1.set_title("Plot Title")
        ax1.set_xlabel("X axis Label")
        ax1.set_xlim([0, 3])
        ax1.set_ylabel("Y axis Label")
        ax1.set_ylim([0, 9])
        plt.subplots_adjust(top=0.925,     # Further fix clipping of text in the figure
                            bottom=0.16,
                            left=0.11,
                            right=0.90,
                            hspace=0.2,
                            wspace=0.2)

        fig1_canvas = FigureCanvasTkAgg(fig1, self.report_frame)        
        fig1_canvas.get_tk_widget().grid(row=0, column=0, sticky="nw")


if __name__ == "__main__":
    root = tk.Tk()
    root.title("Plot Test")

Graph:

enter image description here

Answered By: Michael S.
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.