[PYTHON] Draw a graph with PySimple GUI

What you can read this article

graph_example.jpg

With the PySimple GUI you will be able to:

--You will be able to draw bar graphs, line graphs, etc. --Graph that updates the display regularly

For the basic operation of PySimpleGUI, please refer to If you use Tkinter, try using PySimpleGUI.

Overview

I think there are many people who analyze data as a way to use Python. Also, some people may want to visualize the analysis results with line graphs and bar graphs.

There are roughly two ways to use graphs with PySimpleGUI.

-Draw using graph-element --Embed matplotlib and draw

This time, I will explain how to create using graph-element.

About graph-element

graph-element is a class used for drawing. In tkinter, drawing is done using canvas, but the graph-element of PySimpleGUI is made easier to use by devising the coordinate system of canvs.

As a basic usage Use the Graph class to specify the size of the drawing area, the lower left coordinates (origin) of the drawing area, and the upper right coordinates.

graph = sg.Graph((500,500), (0,0), (500, 500))

After that, we will use each drawing method for the graph.

--DrawCircle: Draw a circle --DrawLine: Draw a line --DrawPoint: Place points --DrawRectangle: Draw a rectangle --DrawOval: Draw an arc --DrawImage: Display the image --DrawText: Draw characters

Of these, the following are used when drawing bar graphs and pie charts.

--DrawLine: Used to draw lines, auxiliary lines, and scales on line graphs. --DrawPoint: Used to draw plotted points on a line chart or to draw an arc like a sine wave --DrawText: Used to display graph labels and values per plot

Also use the following methods.

--Erase: Clears the drawing area. It is used for non to delete the graph that was being drawn when switching graphs. --Move: Moves what is drawn in the x and y directions. Used to move the graph in real time

code

I will post a summary of the official sample code. Switch the contents of the graph with the button

Execution screen graph_example.jpg

code

import PySimpleGUI as sg
from random import randint
import math
"""
The following official samples are integrated into one
https://pysimplegui.trinket.io/demo-programs#/graph-element/graph-element-bar-chart
https://pysimplegui.trinket.io/demo-programs#/graph-element/graph-element-sine-wave
https://pysimplegui.trinket.io/demo-programs#/graph-element/graph-element-line-graph-with-labels
https://pysimplegui.trinket.io/demo-programs#/graph-element/animated-line-graph
"""

#constant
GRAPH_SIZE = (500, 500)
DATA_SIZE = (500, 500)

# 
PLOTS_NUMBER = 30
RAND_MAX = 400

#For polygonal lines
LINE_BAR_WIDTH = 10
LINE_BAR_SPACING = 16
LINE_EDGE_OFFSET = 3

#bar graph
BAR_WIDTH = 50
BAR_SPACING = 75
EDGE_OFFSET = 3

#Sign graph
SIZE_X = GRAPH_SIZE[0]//2
SIZE_Y = GRAPH_SIZE[1]//2
NUMBER_MARKER_FREQUENCY = 25

#Animation
GRAPH_STEP_SIZE = 5
DELAY = 15  #Time interval

#Layout
#Setting the drawing area of the graph
graph = sg.Graph(GRAPH_SIZE, (0, 0), DATA_SIZE,
                 key='-GRAPH-', background_color='white',)

layout = [[sg.Text('chart demo')],
          [graph],
          [sg.Button('LINE'), sg.Button('chart'), sg.Button('Both'), sg.Button('pie chart'), sg.Button('Sine wave'),sg.Button('animation') ]]

window = sg.Window('Simple graph sample', layout)

before_value = 0  #Initialize line graph
delay = x = lastx = lasty = 0  #Animation initialization

is_animated = False


def draw_axis():
    """Draw auxiliary lines on the X and Y axes

Origin at the bottom left of the graph element(0,0)Is set as
Moving with the center of the graph area as the origin
    """

    graph.draw_line((0, SIZE_Y), (SIZE_X*2, SIZE_Y))  #origin
    graph.draw_line((SIZE_X, 0), (SIZE_X, SIZE_Y*2))

    for x in range(0, SIZE_X*2, NUMBER_MARKER_FREQUENCY):
        graph.draw_line((x, SIZE_Y-3), (x, SIZE_Y+3))  #Draw a scale
        if x != 0:
            graph.draw_text(str(x-SIZE_X), (x, SIZE_Y-10),
                            color='green')  #Draw the value of the scale

    for y in range(0, SIZE_Y*2+1, NUMBER_MARKER_FREQUENCY):
        graph.draw_line((SIZE_X-3, y), (SIZE_X+3, y))
        if y != 0:
            graph.draw_text(str(y-SIZE_Y), (SIZE_X-10, y), color='blue')


while True:

    if is_animated:
        #Regularly'__TIMEOUT__'Event is issued
        event, values = window.Read(timeout=DELAY)
    else:
        event, values = window.Read()

    if event is None:
        break

    if event == 'LINE':
        is_animated = False
        #Show labeled line chart
        graph.Erase()  #Graph display Delete both machines

        for i in range(PLOTS_NUMBER):
            graph_value = randint(0, 400)
            if i > 0:
                graph.DrawLine(((i-1) * LINE_BAR_SPACING + LINE_EDGE_OFFSET + LINE_BAR_WIDTH/2,  before_value),
                               (i * LINE_BAR_SPACING + LINE_EDGE_OFFSET + LINE_BAR_WIDTH/2, graph_value), color='green', width=1)

            #Display line label (y value)
            graph.DrawText(text=graph_value, location=(
                i * LINE_BAR_SPACING+EDGE_OFFSET+2, graph_value+10))

            graph.DrawPoint((i * LINE_BAR_SPACING + LINE_EDGE_OFFSET +
                             LINE_BAR_WIDTH/2, graph_value), size=3, color='green',)

            before_value = graph_value

    if event == 'chart':
        is_animated = False

        #Delete bar chart
        graph.Erase()
        for i in range(PLOTS_NUMBER):
            graph_value = randint(0, 400)
            graph.DrawRectangle(top_left=(i * BAR_SPACING + EDGE_OFFSET, graph_value),
                                bottom_right=(i * BAR_SPACING + EDGE_OFFSET + BAR_WIDTH, 0), fill_color='blue')
            graph.DrawText(text=graph_value, location=(
                i*BAR_SPACING+EDGE_OFFSET+25, graph_value+10))

    if event == 'Both':
        is_animated = False

        #Show both line and bar charts
        graph.Erase()
        for i in range(PLOTS_NUMBER):
            graph_value = randint(0, 400)
            graph.DrawRectangle(top_left=(i * BAR_SPACING + EDGE_OFFSET, graph_value),
                                bottom_right=(i * BAR_SPACING + EDGE_OFFSET + BAR_WIDTH, 0), fill_color='blue')
            graph.DrawText(text=graph_value, location=(
                i*BAR_SPACING+EDGE_OFFSET+25, graph_value+10))

            if i > 0:
                graph.DrawLine(((i-1) * LINE_BAR_SPACING + LINE_EDGE_OFFSET + LINE_BAR_WIDTH/2,  before_value),
                               (i * LINE_BAR_SPACING + LINE_EDGE_OFFSET + LINE_BAR_WIDTH/2, graph_value), color='green', width=1)

            graph.DrawText(text=graph_value, location=(
                i * LINE_BAR_SPACING+EDGE_OFFSET+2, graph_value+10))

            graph.DrawPoint((i * LINE_BAR_SPACING + LINE_EDGE_OFFSET +
                             LINE_BAR_WIDTH/2, graph_value), size=3, color='green',)
            before_value = graph_value

    if event == 'pie chart':
        is_animated = False
        graph.erase()
        
        # create_arc()Can't be filled because there is no fill
        graph.DrawArc( (50,50), (DATA_SIZE[0]-50, DATA_SIZE[1]-50), extent=-200, start_angle=90)
        graph.DrawArc( (50,50), (DATA_SIZE[0]-50, DATA_SIZE[1]-50), extent=-400, start_angle=-110 ,arc_color="yellow")
        graph.DrawArc( (50,50), (DATA_SIZE[0]-50, DATA_SIZE[1]-50), extent=-50,  start_angle=-510 , arc_color="blue")
        graph.DrawArc( (50,50), (DATA_SIZE[0]-50, DATA_SIZE[1]-50), extent=-50,  start_angle=-560 , arc_color="red")
        graph.DrawArc( (50,50), (DATA_SIZE[0]-50, DATA_SIZE[1]-50), extent=-20,  start_angle=-610 , arc_color="green")

    if event == 'Sine wave':
        is_animated = False
        graph.erase()

        draw_axis()
        prev_x = prev_y = None
        for x in range(0, SIZE_X*2):
            y = math.sin(x/75)*100 + SIZE_Y
            if prev_x is not None:
                graph.draw_line((prev_x, prev_y), (x, y), color='red')
            prev_x, prev_y = x, y

    if event == 'animation' or is_animated:

        if not is_animated:
            graph.Erase()  #Delete the graph once

        is_animated = True

        #Display a graph that moves in chronological order
        step_size, delay = GRAPH_STEP_SIZE, DELAY
        y = randint(0, GRAPH_SIZE[1])
        if x < GRAPH_SIZE[0]:  #First time
            # window['-GRAPH-'].DrawLine((lastx, lasty), (x, y), width=1)
            graph.DrawLine((lastx, lasty), (x, y), width=1)
        else:
            # window['-GRAPH-'].Move(-step_size, 0)  #Shift the entire graph to the left
            # window['-GRAPH-'].DrawLine((lastx, lasty), (x, y), width=1)
            graph.Move(-step_size, 0)  #Shift the entire graph to the left
            graph.DrawLine((lastx, lasty), (x, y), width=1)
            x -= step_size
            lastx, lasty = x, y
        lastx, lasty = x, y
        x += step_size

window.Close()

The difference from the official graph is that the coordinates of the sine wave started at (0,0) at the origin of the entire canvas this time, so the coordinates of (250,250) are shifted to the origin. In the official sample, the coordinates at the left end are (250, -250). Also, there is no official sample for the pie chart, and I tried to implement it independently using the DrawArc method, but there is no fill parameter that fills the inside of the circle, and the angle specification is unique and time-consuming. So I think it's better to stop making pie charts

By using the graph-element of PySimpleGUI, it is possible to create simple graphs such as bar graphs and line graphs, such as those created with the graph function of Excel.

About official graph related samples

PySimpleGUI has many sample files, and there are many useful samples that can be used as reference for implementation.

--Official demo - https://github.com/PySimpleGUI/PySimpleGUI/tree/master/DemoPrograms

--Official demo 2 - https://pysimplegui.trinket.io/demo-programs#/demo-programs/the-basic-pysimplegui-program

Here are some samples that I personally find useful and interesting.

Cooperation with matplotlib

Demo_Matplotlib.png

Animation to sort

visualizing-sorts.png

Real-time graph showing CPU usage

PySimpleGUI_Rainmeter_CPU_Cores.png

Summary

You can see that you can easily create graphs using PySimpleGUI. In the official sample of PySimpleGUI, there are some other samples using graphs, so please take a look if you are interested.

Recommended Posts

Draw a graph with PySimple GUI
Draw a graph with NetworkX
Draw a graph with networkx
Draw a loose graph with matplotlib
Draw a graph with Julia + PyQtGraph (3)
Draw a graph with pandas + XlsxWriter
Draw a graph with PyQtGraph Part 1-Drawing
Draw a flat surface with a matplotlib 3d graph
Draw a graph with Japanese labels in Jupyter
How to draw a 2-axis graph with pyplot
Draw a graph with PyQtGraph Part 3-PlotWidget settings
Draw a graph by processing with Pandas groupby
[Python] Draw a directed graph with Dash Cytoscape
Draw a graph with PyQtGraph Part 4-PlotItem settings
Draw a graph with matplotlib from a csv file
Draw a graph with PyQtGraph Part 6-Displaying a legend
Draw a graph with PyQtGraph Part 5-Increase the Y-axis
[Python] How to draw a line graph with Matplotlib
Draw a graph with PyQtGraph Part 2--Detailed plot settings
Study math with Python: Draw a sympy (scipy) graph with matplotlib
Let's make a GUI with python.
Draw a beautiful circle with numpy
Multiple file processing with Kivy + Matplotlib + Draw Graph on GUI
[Visualization] I want to draw a beautiful graph with Plotly
Make a nice graph with plotly
Easily draw a map with matplotlib.basemap
[PyQt] Display a multi-axis graph with QtChart
How to draw a graph using Matplotlib
Draw a heart in Ruby with PyCall
Create a GUI app with Python's Tkinter
Display Matplotlib xy graph in PySimple GUI.
Simply draw a graph by specifying a file
Create a graph with borders removed with matplotlib
(Matplotlib) I want to draw a graph with a size specified in pixels
How to draw a bar graph that summarizes multiple series with matplotlib
Draw a graph that can be moved around with HoloViews and Bokeh
Draw a graph of a quadratic function in Python
I made a GUI application with Python + PyQt5
How to draw a 3D graph before optimization
Create a GUI executable file created with tkinter
Draw a "breast curved surface" in a 3D graph (1)
A memo that made a graph animated with plotly
Try to draw a life curve with python
You can easily create a GUI with Python
[Python] Draw a Mickey Mouse with Turtle [Beginner]
Draw a "breast curved surface" in a 3D graph (2)
I made a random number graph with Numpy
Open a file dialog with a python GUI (tkinter.filedialog)
Draw multiple photos in a graph from multiple folders
Draw a graph in Julia ... I tried a little analysis
[Python] Draw a Qiita tag relationship diagram with NetworkX
A4 size with python-pptx
Create a native GUI app with Py2app and Tkinter
I tried to draw a route map with Python
Forcibly draw something like a flowchart with Python, matplotlib
Band graph with matplotlib
Decorate with a decorator
Draw graph in python
[Python] How to draw a scatter plot with Matplotlib
Data visualization with Python-It's too convenient to draw a graph by attribute with "Facet" at once
Create a partial correlation matrix and draw an independent graph