hoffstadt/DearPyGui

Dynamic display GUI

hanjiahe1999 opened this issue · 13 comments

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

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

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

Take a look at this comment: #2257 (comment).

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.

`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

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.

it may be 3.589 - 3.572, it is so small

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

v-ein commented

Where do you place set_axis_limits?

v-ein commented

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).

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

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).

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