hoffstadt / DearPyGui

Dear PyGui: A fast and powerful Graphical User Interface Toolkit for Python with minimal dependencies
https://dearpygui.readthedocs.io/en/latest/
MIT License
12.62k stars 669 forks source link

Dynamic display GUI #2329

Open hanjiahe1999 opened 1 month ago

hanjiahe1999 commented 1 month ago

I am a beginner and am learning dearpygui, I saw the Metrics function in demo.py, I want to look for this script, where can I find it? thanks for your help? ![Uploading 20240515-000454.jpg…]()

v-ein commented 1 month ago

Do you want to open the Metrics window or to see what's under the cover? To open it, use dpg.show_metrics().

The Metrics window itself is implemented in C++, you can find its source code here: https://github.com/hoffstadt/DearPyGui/blob/master/src/mvMetricsWindow.cpp

hanjiahe1999 commented 1 month ago

Wow,this is really cool, would it be possible to implement this functionality in python? Or a case of real-time dynamic curve drawing, like this tables I am currently doing a numerical simulation and want to implement the function of drawing some curves in real time in the DearpyGUI. Could you give me some good suggestions? best use python. thank you for your help.

v-ein commented 1 month ago

Take a look at this comment: https://github.com/hoffstadt/DearPyGui/issues/2257#issuecomment-1899936296.

hanjiahe1999 commented 1 month ago

Wow,it is so cool!!!And,I successfully ran the code! There is also a small problem. How to freely display the y-axis size? dpg.set_axis_limits("data-y-axis-1", 0, 100) does not work.

hanjiahe1999 commented 1 month ago
`from openmm.app import *
import openmm as mm
from openmm import *
from openmm.unit import *
from openmm.unit import picosecond,nanometer
from sys import stdout

import numpy as np

import time
import dearpygui.dearpygui as dpg
dpg.create_context()
dpg.create_viewport(title="Test", width=600, height=500)

def pdb2numpy(path):
    pdb = PDBFile(path)
    forcefield = ForceField('amber14-all.xml','amber14/tip3pfb.xml')
    modeller = Modeller(pdb.topology,pdb.positions)
    modeller.deleteWater()
    residues = modeller.addHydrogens(forcefield)
    modeller.addSolvent(forcefield,padding=1.0*nanometer)
    system = forcefield.createSystem(modeller.topology,nonbondedMethod=PME,nonbondedCutoff=1.0*nanometer,constraints=HBonds)
    num_pos = np.array(modeller.getPositions()._value)
    return num_pos,pdb.topology.getNumAtoms(),modeller.topology.getNumAtoms(),modeller,system

path = 'protein/1aki.pdb'
num_pos,protein_num,sysn_particles,protein_modeller,system = pdb2numpy(path)
integrator = LangevinIntegrator(300*kelvin,1/picosecond,0.004*picosecond)
protein_simulation = Simulation(protein_modeller.topology,system,integrator)

protein_simulation.context.setPositions(protein_modeller.positions)
protein_simulation.minimizeEnergy()
sys_state = protein_simulation.context.getState(getPositions=True,getEnergy=True)

pos = np.array(sys_state.getPositions()._value)
energy = (sys_state.getPotentialEnergy()._value / 1e5)

dpg.setup_dearpygui()
with dpg.window() as w:
    TOTAL_VALUES = 50
    x_values = [i for i in range(TOTAL_VALUES)]
    y_values = [0] * TOTAL_VALUES
    last_update = time.time()

    def update_data():
        global y_values, last_update

        if time.time() - last_update < 0.5:
            return
        last_update = time.time()

        y_values = y_values[1:]
        y_values.append(energy)
        dpg.configure_item("data-row-1", y1=y_values)
        dpg.fit_axis_data("data-y-axis-1")

    with dpg.item_handler_registry() as handlers:
        dpg.add_item_visible_handler(callback=update_data)

    with dpg.plot(height=200, no_box_select=True, no_mouse_pos=True):
        dpg.bind_item_handler_registry(dpg.last_item(), handlers)

        xaxis = dpg.add_plot_axis(dpg.mvXAxis, no_tick_marks=True, no_tick_labels=True, no_gridlines=True)
        with dpg.plot_axis(dpg.mvYAxis, tag="data-y-axis-1", no_tick_marks=True, no_tick_labels=True, no_gridlines=True):
            dpg.add_shade_series(x_values, y_values, tag="data-row-1")
        dpg.fit_axis_data(xaxis)

dpg.show_viewport()
while dpg.is_dearpygui_running():

    sys_state = protein_simulation.context.getState(getPositions=True,getEnergy=True)
    protein_simulation.step(1)
    dpg.render_dearpygui_frame()

dpg.destroy_context()

20240516-004409

I use the openMM to do the simulation website: https://openmm.github.io/openmm-cookbook/latest/tutorials

there is simple demo,I want to plot the system potiential energy, it changes is so small but i want to show this change

v-ein commented 1 month ago

What's the range of your Y values (energy) ? It might help if you set no_tick_marks on the Y axis to False for a while - to see if the limit actually gets applied.

hanjiahe1999 commented 1 month ago

it may be 3.589 - 3.572, it is so small

hanjiahe1999 commented 1 month ago

If there is a way to achieve this effect using python, it would be the best!!! 20240516-012834

v-ein commented 1 month ago

Where do you place set_axis_limits?

v-ein commented 1 month ago

Try to replace dpg.fit_axis_data("data-y-axis-1") with dpg.set_axis_limits("data-y-axis-1", 0, 100) (or whatever limits you need).

hanjiahe1999 commented 1 month ago

I finish it !!!!!Amazing GUI !!! 20240516-022827

But, sorry to bother you again, I have some other questions. If I want to draw two such lines, do I need two update functions,two callback function?

from random import randrange
import time
import dearpygui.dearpygui as dpg

dpg.create_context()
dpg.create_viewport(title="Test", width=600, height=500)

dpg.setup_dearpygui()
with dpg.window() as w:
    TOTAL_VALUES = 50
    x_values = [i for i in range(TOTAL_VALUES)]
    y_values = [0] * TOTAL_VALUES
    z_values = [0] * TOTAL_VALUES
    last_update = time.time()

    def update_data():
        global y_values, last_update

        # Make sure we're not too fast
        if time.time() - last_update < 0.3:
            return
        last_update = time.time()
        y_values = y_values[1:]
        y_values.append(randrange(0, 100))
        z_values = z_values[1:]
        z_values.append(randrange(0, 100))

        dpg.configure_item("data-row-1", y1=y_values)
        dpg.configure_item("data-row-2", y2=z_values)

        dpg.fit_axis_data("data-y-axis-1")
        dpg.fit_axis_data("data-y-axis-2")

    with dpg.item_handler_registry() as handlers:
        dpg.add_item_visible_handler(callback=update_data)

    with dpg.plot(height=100, no_box_select=True, no_mouse_pos=True):
        dpg.bind_item_handler_registry(dpg.last_item(), handlers)

        xaxis = dpg.add_plot_axis(dpg.mvXAxis, no_tick_marks=True, no_tick_labels=True, no_gridlines=True)
        with dpg.plot_axis(dpg.mvYAxis, tag="data-y-axis-1", no_tick_marks=True, no_tick_labels=True, no_gridlines=True):
            dpg.add_shade_series(x_values, y_values, tag="data-row-1")

        dpg.fit_axis_data(xaxis)

    with dpg.plot(height=100, no_box_select=True, no_mouse_pos=True):
        dpg.bind_item_handler_registry(dpg.last_item(), handlers)

        xaxis = dpg.add_plot_axis(dpg.mvXAxis, no_tick_marks=True, no_tick_labels=True,no_gridlines=True)
        with dpg.plot_axis(dpg.mvYAxis, tag="data-y-axis-2", no_tick_marks=True, no_tick_labels=True, no_gridlines=True):
            dpg.add_shade_series(x_values, z_values, tag="data-row-2")

        dpg.fit_axis_data(xaxis)

dpg.show_viewport()
while dpg.is_dearpygui_running():
    # insert here any code you would like to run in the render loop
    # you can manually stop by using stop_dearpygui()

    dpg.render_dearpygui_frame()
    # print(y_values[9])
dpg.destroy_context()

this code can't run

v-ein commented 1 month ago

When you bind handlers to both plots, DPG invokes the "item visible" handler twice per frame, provided both plots are visible. This means update_data will be called 2x more often than it did for one graph. The last_update condition will filter it out, so no problem here, just wanted to point out how it really works.

You say "this conde can't run" - did you see the error message? It's pretty straightforward:

local variable 'z_values' referenced before assignment

You're using z_values but it's not listed as global (search the code for y_values and you'll see).

hanjiahe1999 commented 1 month ago

thank you so so much!! i finished it prefectly!!thank you for your answer sincerely !!