import dearpygui.dearpygui as dpg import math from math import sin, cos, log10 import random import webbrowser count_2d_histogram = 50_000 xybin_2d_histogram = [100, 100] t_digital_plot = 0 def _help(message): last_item = dpg.last_item() group = dpg.add_group(horizontal=True) dpg.move_item(last_item, parent=group) dpg.capture_next_item(lambda s: dpg.move_item(s, parent=group)) t = dpg.add_text("(?)", color=[0, 255, 0]) with dpg.tooltip(t): dpg.add_text(message) def _hyperlink(text, address): b = dpg.add_button(label=text, callback=lambda:webbrowser.open(address)) dpg.bind_item_theme(b, "__demo_hyperlinkTheme") def _config(sender, keyword, user_data): widget_type = dpg.get_item_type(sender) items = user_data if widget_type == "mvAppItemType::mvRadioButton": value = True else: keyword = dpg.get_item_label(sender) value = dpg.get_value(sender) if isinstance(user_data, list): for item in items: dpg.configure_item(item, **{keyword: value}) else: dpg.configure_item(items, **{keyword: value}) def _add_config_options(item, columns, *names, **kwargs): if columns == 1: if 'before' in kwargs: for name in names: dpg.add_checkbox(label=name, callback=_config, user_data=item, before=kwargs['before'], default_value=dpg.get_item_configuration(item)[name]) else: for name in names: dpg.add_checkbox(label=name, callback=_config, user_data=item, default_value=dpg.get_item_configuration(item)[name]) else: if 'before' in kwargs: dpg.push_container_stack(dpg.add_table(header_row=False, before=kwargs['before'])) else: dpg.push_container_stack(dpg.add_table(header_row=False)) for i in range(columns): dpg.add_table_column() for i in range((len(names)+(columns - 1))//columns): with dpg.table_row(): for j in range(columns): if (i*columns + j) >= len(names): break dpg.add_checkbox(label=names[i*columns + j], callback=_config, user_data=item, default_value=dpg.get_item_configuration(item)[names[i*columns + j]]) dpg.pop_container_stack() def _add_config_option(item, default_value, *names): dpg.add_radio_button(names, default_value=default_value, callback=_config, user_data=item) def _hsv_to_rgb(h, s, v): if s == 0.0: return (v, v, v) i = int(h*6.) # XXX assume int() truncates! f = (h*6.)-i; p,q,t = v*(1.-s), v*(1.-s*f), v*(1.-s*(1.-f)); i%=6 if i == 0: return (255*v, 255*t, 255*p) if i == 1: return (255*q, 255*v, 255*p) if i == 2: return (255*p, 255*v, 255*t) if i == 3: return (255*p, 255*q, 255*v) if i == 4: return (255*t, 255*p, 255*v) if i == 5: return (255*v, 255*p, 255*q) def _create_static_textures(): ## create static textures texture_data1 = [] for i in range(100*100): texture_data1.append(255/255) texture_data1.append(0) texture_data1.append(255/255) texture_data1.append(255/255) texture_data2 = [] for i in range(50*50): texture_data2.append(255/255) texture_data2.append(255/255) texture_data2.append(0) texture_data2.append(255/255) texture_data3 = [] for row in range(50): for column in range(50): texture_data3.append(255/255) texture_data3.append(0) texture_data3.append(0) texture_data3.append(255/255) for column in range(50): texture_data3.append(0) texture_data3.append(255/255) texture_data3.append(0) texture_data3.append(255/255) for row in range(50): for column in range(50): texture_data3.append(0) texture_data3.append(0) texture_data3.append(255/255) texture_data3.append(255/255) for column in range(50): texture_data3.append(255/255) texture_data3.append(255/255) texture_data3.append(0) texture_data3.append(255/255) dpg.add_static_texture(100, 100, texture_data1, parent="__demo_texture_container", tag="__demo_static_texture_1", label="Static Texture 1") dpg.add_static_texture(50, 50, texture_data2, parent="__demo_texture_container", tag="__demo_static_texture_2", label="Static Texture 2") dpg.add_static_texture(100, 100, texture_data3, parent="__demo_texture_container", tag="__demo_static_texture_3", label="Static Texture 3") def _create_dynamic_textures(): ## create dynamic textures texture_data1 = [] for i in range(100*100): texture_data1.append(255/255) texture_data1.append(0) texture_data1.append(255/255) texture_data1.append(255/255) texture_data2 = [] for i in range(50*50): texture_data2.append(255/255) texture_data2.append(255/255) texture_data2.append(0) texture_data2.append(255/255) dpg.add_dynamic_texture(100, 100, texture_data1, parent="__demo_texture_container", tag="__demo_dynamic_texture_1") dpg.add_dynamic_texture(50, 50, texture_data2, parent="__demo_texture_container", tag="__demo_dynamic_texture_2") def _update_dynamic_textures(sender, app_data, user_data): new_color = app_data new_color[0] = new_color[0] new_color[1] = new_color[1] new_color[2] = new_color[2] new_color[3] = new_color[3] if user_data == 1: texture_data = [] for i in range(100*100): texture_data.append(new_color[0]) texture_data.append(new_color[1]) texture_data.append(new_color[2]) texture_data.append(new_color[3]) dpg.set_value("__demo_dynamic_texture_1", texture_data) elif user_data == 2: texture_data = [] for i in range(50*50): texture_data.append(new_color[0]) texture_data.append(new_color[1]) texture_data.append(new_color[2]) texture_data.append(new_color[3]) dpg.set_value("__demo_dynamic_texture_2", texture_data) def _on_demo_close(sender, app_data, user_data): dpg.delete_item(sender) dpg.delete_item("__demo_texture_container") dpg.delete_item("__demo_colormap_registry") dpg.delete_item("__demo_hyperlinkTheme") dpg.delete_item("__demo_theme_progressbar") dpg.delete_item("stock_theme1") dpg.delete_item("stock_theme2") dpg.delete_item("stock_theme3") dpg.delete_item("stock_theme4") dpg.delete_item("stem_theme1") dpg.delete_item("__demo_keyboard_handler") dpg.delete_item("__demo_mouse_handler") dpg.delete_item("__demo_filedialog") dpg.delete_item("__demo_stage1") dpg.delete_item("__demo_popup1") dpg.delete_item("__demo_popup2") dpg.delete_item("__demo_popup3") dpg.delete_item("__demo_item_reg3") dpg.delete_item("__demo_item_reg6") dpg.delete_item("__demo_item_reg7") dpg.delete_item("demoitemregistry") for i in range(7): dpg.delete_item("__demo_theme"+str(i)) dpg.delete_item("__demo_theme2_"+str(i)) for i in range(5): dpg.delete_item("__demo_item_reg1_"+str(i)) dpg.delete_item("__demo_item_reg2_"+str(i)) for i in range(3): dpg.delete_item("__demo_item_reg4_"+str(i)) for i in range(4): dpg.delete_item("__demo_item_reg5_"+str(i)) def show_demo(): dpg.add_texture_registry(label="Demo Texture Container", tag="__demo_texture_container") dpg.add_colormap_registry(label="Demo Colormap Registry", tag="__demo_colormap_registry") with dpg.theme(tag="__demo_hyperlinkTheme"): with dpg.theme_component(dpg.mvButton): dpg.add_theme_color(dpg.mvThemeCol_Button, [0, 0, 0, 0]) dpg.add_theme_color(dpg.mvThemeCol_ButtonActive, [0, 0, 0, 0]) dpg.add_theme_color(dpg.mvThemeCol_ButtonHovered, [29, 151, 236, 25]) dpg.add_theme_color(dpg.mvThemeCol_Text, [29, 151, 236]) def _log(sender, app_data, user_data): print(f"sender: {sender}, \t app_data: {app_data}, \t user_data: {user_data}") _create_static_textures() _create_dynamic_textures() with dpg.window(label="Dear PyGui Demo", width=800, height=800, on_close=_on_demo_close, pos=(100, 100), tag="__demo_id"): with dpg.menu_bar(): with dpg.menu(label="Menu"): dpg.add_text("This menu is just for show!") dpg.add_menu_item(label="New") dpg.add_menu_item(label="Open") with dpg.menu(label="Open Recent"): dpg.add_menu_item(label="harrel.c") dpg.add_menu_item(label="patty.h") dpg.add_menu_item(label="nick.py") dpg.add_menu_item(label="Save") dpg.add_menu_item(label="Save As...") with dpg.menu(label="Settings"): dpg.add_menu_item(label="Option 1", callback=_log) dpg.add_menu_item(label="Option 2", check=True, callback=_log) dpg.add_menu_item(label="Option 3", check=True, default_value=True, callback=_log) with dpg.child_window(height=60, autosize_x=True, delay_search=True): for i in range(10): dpg.add_text(f"Scolling Text{i}") dpg.add_slider_float(label="Slider Float") dpg.add_input_int(label="Input Int") dpg.add_combo(("Yes", "No", "Maybe"), label="Combo") with dpg.menu(label="Tools"): dpg.add_menu_item(label="Show About", callback=lambda:dpg.show_tool(dpg.mvTool_About)) dpg.add_menu_item(label="Show Metrics", callback=lambda:dpg.show_tool(dpg.mvTool_Metrics)) dpg.add_menu_item(label="Show Documentation", callback=lambda:dpg.show_tool(dpg.mvTool_Doc)) dpg.add_menu_item(label="Show Debug", callback=lambda:dpg.show_tool(dpg.mvTool_Debug)) dpg.add_menu_item(label="Show Style Editor", callback=lambda:dpg.show_tool(dpg.mvTool_Style)) dpg.add_menu_item(label="Show Font Manager", callback=lambda:dpg.show_tool(dpg.mvTool_Font)) dpg.add_menu_item(label="Show Item Registry", callback=lambda:dpg.show_tool(dpg.mvTool_ItemRegistry)) dpg.add_menu_item(label="Show Stack Tool", callback=lambda:dpg.show_tool(dpg.mvTool_Stack)) with dpg.menu(label="Settings"): dpg.add_menu_item(label="Wait For Input", check=True, callback=lambda s, a: dpg.configure_app(wait_for_input=a)) dpg.add_menu_item(label="Toggle Fullscreen", callback=lambda:dpg.toggle_viewport_fullscreen()) with dpg.group(horizontal=True): dpg.add_loading_indicator(circle_count=4) with dpg.group(): dpg.add_text(f'Dear PyGui says hello. ({dpg.get_dearpygui_version()})') with dpg.group(horizontal=True): dpg.add_text("The code for the most recent version of this demo can be found here:") _hyperlink("demo.py", "https://github.com/hoffstadt/DearPyGui/blob/master/dearpygui/demo.py") with dpg.collapsing_header(label="Window Options"): _add_config_options("__demo_id", 3, "no_title_bar", "no_scrollbar", "menubar", "no_move", "no_resize", "no_collapse", "no_close", "no_background", "no_bring_to_front_on_focus", "unsaved_document" ) with dpg.collapsing_header(label="Widgets"): with dpg.tree_node(label="Basic"): with dpg.group(horizontal=True): dpg.add_button(label="Button", callback=_log) dpg.add_button(label="Button", callback=_log, small=True) dpg.add_button(label="Button", callback=_log, arrow=True) # default direction is mvDir_Up dpg.add_button(label="Button", callback=_log, arrow=True, direction=dpg.mvDir_Left) dpg.add_button(label="Button", callback=_log, arrow=True, direction=dpg.mvDir_Right) dpg.add_button(label="Button", callback=_log, arrow=True, direction=dpg.mvDir_Down) dpg.add_button(label="Hold me button", callback=_log, repeat=True) dpg.add_checkbox(label="checkbox", callback=_log) dpg.add_radio_button(("radio a", "radio b", "radio c"), callback=_log, horizontal=True) dpg.add_selectable(label="selectable", callback=_log) with dpg.group(horizontal=True): for i in range(7): with dpg.theme(tag="__demo_theme"+str(i)): with dpg.theme_component(dpg.mvButton): dpg.add_theme_color(dpg.mvThemeCol_Button, _hsv_to_rgb(i/7.0, 0.6, 0.6)) dpg.add_theme_color(dpg.mvThemeCol_ButtonActive, _hsv_to_rgb(i/7.0, 0.8, 0.8)) dpg.add_theme_color(dpg.mvThemeCol_ButtonHovered, _hsv_to_rgb(i/7.0, 0.7, 0.7)) dpg.add_theme_style(dpg.mvStyleVar_FrameRounding, i*5) dpg.add_theme_style(dpg.mvStyleVar_FramePadding, i*3, i*3) dpg.add_button(label="Click", callback=_log) dpg.bind_item_theme(dpg.last_item(), "__demo_theme"+str(i)) with dpg.group(horizontal=True): dpg.add_text("Press a button: ") widget = dpg.add_text("0") dpg.add_button(arrow=True, direction=dpg.mvDir_Left, user_data=widget, callback=lambda s, a, u: dpg.set_value(u, int(dpg.get_value(u))-1)) dpg.add_button(arrow=True, direction=dpg.mvDir_Right, user_data=widget, callback=lambda s, a, u: dpg.set_value(u, int(dpg.get_value(u))+1)) dpg.add_text("hover me") with dpg.tooltip(dpg.last_item()): dpg.add_text("I'm a simple tooltip!") dpg.add_separator(label="This is a separator with text") dpg.add_text("Value", label="Label", show_label=True) dpg.add_combo(("AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK"), label="combo", default_value="AAAA", callback=_log) dpg.add_input_text(label="input text", default_value="Hello, world!", callback=_log) _help( "USER:\n" "Hold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or double-click to select all.\n" "CTRL+X,CTRL+C,CTRL+V clipboard.\n" "CTRL+Z,CTRL+Y undo/redo.\n" "ESCAPE to revert.\n\n") dpg.add_input_text(label="input text (w/ hint)", hint="enter text here", callback=_log) dpg.add_input_int(label="input int", callback=_log) dpg.add_input_float(label="input float", callback=_log, format="%.06f") dpg.add_input_float(label="input float scientific", format="%e", callback=_log) dpg.add_input_floatx(label="input floatx", callback=_log, default_value=[1,2,3,4]) dpg.add_input_double(label="input double", callback=_log, format="%.14f") dpg.add_input_doublex(label="input doublex", callback=_log, default_value=[1,2,3,4], format="%.14f") dpg.add_drag_int(label="drag int", callback=_log) _help( "Click and drag to edit value.\n" "Hold SHIFT/ALT for faster/slower edit.\n" "Double-click or CTRL+click to input value.") dpg.add_drag_int(label="drag int 0..100", format="%d%%", callback=_log) dpg.add_drag_float(label="drag float", callback=_log) dpg.add_drag_float(label="drag small float", default_value=0.0067, format="%.06f ns", callback=_log) dpg.add_slider_int(label="slider int", max_value=3, callback=_log) _help("CTRL+click to enter value.") dpg.add_slider_float(label="slider float", max_value=1.0, format="ratio = %.3f", callback=_log) dpg.add_slider_double(label="slider double", max_value=1.0, format="ratio = %.14f", callback=_log) dpg.add_slider_int(label="slider angle", min_value=-360, max_value=360, format="%d deg", callback=_log) dpg.add_color_edit((102, 179, 0, 128), label="color edit 4", callback=_log) _help( "Click on the colored square to open a color picker.\n" "Click and hold to use drag and drop.\n" "Right-click on the colored square to show options.\n" "CTRL+click on individual component to input value.\n") dpg.add_color_edit(default_value=(.5, 1, .25, .1), label="color edit 4", callback=_log) dpg.add_listbox(("Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pineapple", "Strawberry", "Watermelon"), label="listbox", num_items=4, callback=_log) dpg.add_color_button() with dpg.tree_node(label="Combo"): items = ("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z") combo_id = dpg.add_combo(items, label="combo", height_mode=dpg.mvComboHeight_Small, tag="combo_demo") _add_config_options(combo_id, 1, "popup_align_left", "no_arrow_button", "no_preview", "fit_width") def change_combo_height(sender, app_data, user_data): if app_data == "mvComboHeight_Small": dpg.configure_item("combo_demo", height_mode=dpg.mvComboHeight_Small) elif app_data == "mvComboHeight_Regular": dpg.configure_item("combo_demo", height_mode=dpg.mvComboHeight_Regular) elif app_data == "mvComboHeight_Large": dpg.configure_item("combo_demo", height_mode=dpg.mvComboHeight_Large) elif app_data == "mvComboHeight_Largest": dpg.configure_item("combo_demo", height_mode=dpg.mvComboHeight_Largest) dpg.add_radio_button(("mvComboHeight_Small", "mvComboHeight_Regular", "mvComboHeight_Large", "mvComboHeight_Largest"), callback=change_combo_height, user_data=combo_id, horizontal=True) with dpg.tree_node(label="Color Picker & Edit"): _color_picker_id = dpg.generate_uuid() _color_edit_id = dpg.generate_uuid() def _color_picker_configs(sender, value, user_data): _old_config = dpg.get_item_configuration(user_data) if user_data ==_color_picker_id: picker_mode = _old_config["picker_mode"] else: display_mode = _old_config["display_mode"] alpha_preview = _old_config["alpha_preview"] display_type = _old_config["display_type"] input_mode = _old_config["input_mode"] # picker_mode if value == "mvColorPicker_bar": picker_mode=dpg.mvColorPicker_bar elif value == "mvColorPicker_wheel": picker_mode = dpg.mvColorPicker_wheel # alpha_preview elif value == "mvColorEdit_AlphaPreviewNone": alpha_preview=dpg.mvColorEdit_AlphaPreviewNone elif value == "mvColorEdit_AlphaPreview": alpha_preview = dpg.mvColorEdit_AlphaPreview elif value == "mvColorEdit_AlphaPreviewHalf": alpha_preview = dpg.mvColorEdit_AlphaPreviewHalf # display_type elif value == "mvColorEdit_uint8": display_type=dpg.mvColorEdit_uint8 elif value == "mvColorEdit_float": display_type = dpg.mvColorEdit_float # display_type elif value == "mvColorEdit_uint8": display_type=dpg.mvColorEdit_uint8 elif value == "mvColorEdit_float": display_type = dpg.mvColorEdit_float # display_mode elif value == "mvColorEdit_rgb": display_mode=dpg.mvColorEdit_rgb elif value == "mvColorEdit_hsv": display_mode = dpg.mvColorEdit_hsv elif value == "mvColorEdit_hex": display_mode = dpg.mvColorEdit_hex if user_data ==_color_picker_id: dpg.configure_item(user_data, picker_mode=picker_mode, alpha_preview=alpha_preview, display_type=display_type, input_mode=input_mode ) else: dpg.configure_item(user_data, alpha_preview=alpha_preview, display_type=display_type, input_mode=input_mode, display_mode=display_mode ) dpg.add_text("Color Picker") with dpg.group(horizontal=True) as _before_id: dpg.add_text("picker_mode:") dpg.add_radio_button(("mvColorPicker_bar", "mvColorPicker_wheel"), callback=_color_picker_configs, user_data=_color_picker_id, horizontal=True) with dpg.group(horizontal=True): dpg.add_text("alpha_preview:") dpg.add_radio_button(("mvColorEdit_AlphaPreviewNone", "mvColorEdit_AlphaPreview", "mvColorEdit_AlphaPreviewHalf"), callback=_color_picker_configs, user_data=_color_picker_id, horizontal=True) with dpg.group(horizontal=True): dpg.add_text("display_type:") dpg.add_radio_button(("mvColorEdit_uint8", "mvColorEdit_float"), callback=_color_picker_configs, user_data=_color_picker_id, horizontal=True) with dpg.group(horizontal=True): dpg.add_text("input_mode:") dpg.add_radio_button(("mvColorEdit_input_rgb", "mvColorEdit_input_hsv"), callback=_color_picker_configs, user_data=_color_picker_id, horizontal=True) dpg.add_color_picker((255, 0, 255, 200), label="Color Picker", alpha_preview=True, no_alpha=False, alpha_bar=True, width=200, tag=_color_picker_id) _add_config_options(_color_picker_id, 3, "no_alpha", "no_side_preview", "display_rgb", "display_hsv", "display_hex", "no_small_preview", "no_inputs", "no_tooltip", "no_label", "alpha_bar", before=_before_id) dpg.add_separator() dpg.add_text("Color Edit") with dpg.group(horizontal=True): _before_id = dpg.add_text("alpha_preview:") dpg.add_radio_button(("mvColorEdit_AlphaPreviewNone", "mvColorEdit_AlphaPreview", "mvColorEdit_AlphaPreviewHalf"), callback=_color_picker_configs, user_data=_color_edit_id, horizontal=True) with dpg.group(horizontal=True): dpg.add_text("display_type:") dpg.add_radio_button(("mvColorEdit_uint8", "mvColorEdit_float"), callback=_color_picker_configs, user_data=_color_edit_id, horizontal=True) with dpg.group(horizontal=True): dpg.add_text("display_mode:") dpg.add_radio_button(("mvColorEdit_rgb", "mvColorEdit_hsv", "mvColorEdit_hex"), callback=_color_picker_configs, user_data=_color_edit_id, horizontal=True) with dpg.group(horizontal=True): dpg.add_text("input_mode:") dpg.add_radio_button(("mvColorEdit_input_rgb", "mvColorEdit_input_hsv"), callback=_color_picker_configs, user_data=_color_edit_id, horizontal=True) dpg.add_color_edit((255, 0, 255, 255), label="Color Edit", width=200, tag=_color_edit_id) _add_config_options(_color_edit_id, 3, "no_alpha", "no_picker", "no_options", "no_inputs", "no_small_preview", "no_tooltip", "no_label", "no_drag_drop", "alpha_bar", before=_before_id) with dpg.tree_node(label="Colormaps"): dpg.add_text("Notes") dpg.add_text("Colormaps belong to a mvColorMapRegistry.", bullet=True, indent=20) with dpg.group(horizontal=True): dpg.add_text("Showing the registry will help with debugging. Press ", bullet=True, indent=20) dpg.add_button(label="here", small=True, callback=lambda:dpg.show_item("__demo_colormap_registry")) dpg.add_text("Colormaps are applied with 'bind_colormap(item_id, colormap_id)", bullet=True, indent=20) dpg.add_text("Colormaps can be applied to mvPlot, mvColorMapButton, mvColorMapSlider, mvColorMapScale", bullet=True, indent=20) dpg.add_text("Colormaps can be sampled with 'sample_colormap(colormap_id, t)' (0 10: dpg.set_x_scroll(user_data[1], x_scroll-10) elif user_data[0] == "left": dpg.set_x_scroll(user_data[1], 0) if user_data[0] == "right" and x_scroll < max_scroll-10: dpg.set_x_scroll(user_data[1], x_scroll+10) elif user_data[0] == "right": dpg.set_x_scroll(user_data[1], max_scroll) with dpg.group(horizontal=True): dpg.add_button(label="<<", small=True, user_data=["left", _child_id], callback=_scroll_programmatically) dpg.add_text("Scroll from code") dpg.add_button(label=">>", small=True, user_data=["right", _child_id], callback=_scroll_programmatically) _text_id = dpg.add_text("0/0") with dpg.item_handler_registry(tag="__demo_item_reg3"): dpg.add_item_visible_handler(user_data=[_text_id, _child_id], callback=_update_xscroll_info) dpg.bind_item_handler_registry(_text_id, dpg.last_container()) with dpg.collapsing_header(label="Textures & Images"): with dpg.tree_node(label="Help"): dpg.add_separator() dpg.add_text("ABOUT TEXTURES:") dpg.add_text("Textures are buffers of RGBA data.", bullet=True, indent=20) dpg.add_text("Textures are used by 'image based' widgets:", bullet=True, indent=20) dpg.add_text("add_image", bullet=True, indent=50) dpg.add_text("add_image_button", bullet=True, indent=50) dpg.add_text("draw_image", bullet=True, indent=50) dpg.add_text("add_image_series", bullet=True, indent=50) dpg.add_text("Textures are themselves widgets.", bullet=True, indent=20) dpg.add_text("Textures must be a child of a texture container widget.", bullet=True, indent=20) dpg.add_text("Textures can be either static or dynamic (see following sections).", bullet=True, indent=20) dpg.add_separator() dpg.add_text("PROGRAMMER GUIDE:") dpg.add_text("'image based' widgets hold a reference to a texture widget.", bullet=True, indent=20) dpg.add_text("Deleting the texture widget will not affect widget's using it.", bullet=True, indent=50) dpg.add_text("Textures are only free'd from the GPU when the reference count reaches 0.", bullet=True, indent=50) dpg.add_text("The texture container widget is a root (has no parent).", bullet=True, indent=20) dpg.add_text("The texture container widget is hidden by default.", bullet=True, indent=20) with dpg.group(horizontal=True): dpg.add_text("'Showing' it, opens a manager to inspect the textures within.", bullet=True, indent=50) dpg.add_button(label="Press Here", small=True, callback=lambda:dpg.configure_item("__demo_texture_container", show=True)) dpg.add_separator() with dpg.tree_node(label="Static Textures"): dpg.add_separator() dpg.add_text("ABOUT STATIC TEXTURES:") dpg.add_text("Can NOT be modified after creation.", bullet=True, indent=20) dpg.add_text("Can be loaded from a file using the 'file' keyword.", bullet=True, indent=20) dpg.add_separator() with dpg.group(horizontal=True): with dpg.group(): dpg.add_text("Image Button") dpg.add_image_button("__demo_static_texture_1") with dpg.group(): dpg.add_text("Image") dpg.add_image("__demo_static_texture_2") with dpg.group(): dpg.add_text("Image (texture size)") dpg.add_image("__demo_static_texture_3") with dpg.group(): dpg.add_text("Image (2x texture size)") dpg.add_image("__demo_static_texture_3", width=200, height=200) dpg.add_image(dpg.mvFontAtlas) with dpg.tree_node(label="Dynamic Textures"): dpg.add_separator() dpg.add_text("ABOUT DYNAMIC TEXTURES:") dpg.add_text("Can be modified after creation with 'set_value'.", bullet=True, indent=20) dpg.add_text("New data must be the same dimensions as the original", bullet=True, indent=20) dpg.add_separator() with dpg.group(horizontal=True): with dpg.group(): dpg.add_color_picker((255, 0, 255, 255), label="Texture 1", no_side_preview=True, alpha_bar=True, width=200, callback=_update_dynamic_textures, user_data=1) dpg.add_text("Image Button") dpg.add_image_button("__demo_dynamic_texture_1", width=100, height=100) with dpg.group(): dpg.add_color_picker((255, 255, 0, 255), label="Texture 2", no_side_preview=True, alpha_bar=True, width=200, callback=_update_dynamic_textures, user_data=2) dpg.add_text("Image") dpg.add_image("__demo_dynamic_texture_2") with dpg.tree_node(label="Image Series (plots)"): with dpg.plot(label="Image Plot", height=400, width=-1): dpg.add_plot_legend() dpg.add_plot_axis(dpg.mvXAxis, label="x axis") with dpg.plot_axis(dpg.mvYAxis, label="y axis"): dpg.add_image_series(dpg.mvFontAtlas, [300, 300], [400, 400], label="font atlas") dpg.add_image_series("__demo_static_texture_1", [0, 0], [100, 100], label="static 1") dpg.add_image_series("__demo_static_texture_2", [150, 150], [200, 200], label="static 2") dpg.add_image_series("__demo_static_texture_3", [200, -150], [300, -50], label="static 3") dpg.add_image_series("__demo_dynamic_texture_1", [-200, 100], [-100, 200], label="dynamic 1") dpg.add_image_series("__demo_dynamic_texture_2", [-200, -100], [-150, -50], label="dynamic 2") with dpg.tree_node(label="Drawlists"): with dpg.drawlist(width=400, height=300): dpg.draw_rectangle((0, 0), (400, 300), color=(100, 100, 100, 250), thickness=2) dpg.draw_image("__demo_static_texture_3", [0, 0], [100, 100]) dpg.draw_image("__demo_dynamic_texture_1", [200, 100], [300, 200]) with dpg.collapsing_header(label="Popups & Modal Windows"): with dpg.tree_node(label="Popups"): popup_values = ["Bream", "Haddock", "Mackerel", "Pollock", "Tilefish"] dpg.add_text("This is a light wrapper over a window.", bullet=True) dpg.add_text("For more control over a modal|popup window use a normal window with the modal|popup keyword and set the item handler and mouse events manually.", bullet=True) dpg.add_text("By default a popup will shrink fit the items it contains.This is useful for context windows, and simple modal window popups.", bullet=True) dpg.add_text("When a popup is active, it inhibits interacting with windows that are behind the popup. Clicking outside the popup closes it.", bullet=True) with dpg.group(horizontal=True): b = dpg.add_button(label="Right Click...") t = dpg.add_text("") with dpg.popup(b, tag="__demo_popup1"): dpg.add_text("Aquariam") dpg.add_separator() for i in popup_values: dpg.add_selectable(label=i, user_data=[t, i], callback=lambda s, a, u: dpg.set_value(u[0], u[1])) dpg.add_text("A Popup with minimum size that cannot be moved", bullet=True) with dpg.group(horizontal=True): b = dpg.add_button(label="Right Click...") t = dpg.add_text("") with dpg.popup(b, tag="__demo_popup2", no_move=True, min_size=[300,400]): dpg.add_text("Aquariam") dpg.add_separator() for i in popup_values: dpg.add_selectable(label=i, user_data=[t, i], callback=lambda s, a, u: dpg.set_value(u[0], u[1])) with dpg.tree_node(label="Modals"): dpg.add_text("Modal windows are like popups but the user cannot close them by clicking outside.") dpg.add_text("This popup uses left click") dpg.add_button(label="Left Click...") with dpg.popup(dpg.last_item(), modal=True, mousebutton=dpg.mvMouseButton_Left, tag="__demo_popup3"): dpg.add_text("All those beautiful files will be deleted.\nThis operation cannot be undone!") dpg.add_separator() dpg.add_checkbox(label="Don't ask me next time") with dpg.group(horizontal=True): dpg.add_button(label="OK", width=75, callback=lambda: dpg.configure_item("__demo_popup3", show=False)) dpg.add_button(label="Cancel", width=75, callback=lambda: dpg.configure_item("__demo_popup3", show=False)) with dpg.tree_node(label="File/Directory Selector"): with dpg.file_dialog(label="Demo File Dialog", width=300, height=400, show=False, callback=lambda s, a, u : print(s, a, u), tag="__demo_filedialog"): dpg.add_file_extension(".*", color=(255, 255, 255, 255)) dpg.add_file_extension("Source files (*.cpp *.h *.hpp){.cpp,.h,.hpp}", color=(0, 255, 255, 255)) dpg.add_file_extension(".cpp", color=(255, 255, 0, 255)) dpg.add_file_extension(".h", color=(255, 0, 255, 255), custom_text="header") dpg.add_file_extension("Python(.py){.py}", color=(0, 255, 0, 255)) #dpg.add_button(label="Button on file dialog") dpg.add_button(label="Show File Selector", user_data=dpg.last_container(), callback=lambda s, a, u: dpg.configure_item(u, show=True)) with dpg.collapsing_header(label="Tooltips"): dpg.add_text("Hover me for a fancy tooltip") with dpg.tooltip(dpg.last_item()): dpg.add_simple_plot(label="", default_value=(0.3, 0.9, 2.5, 8.9), height = 80) with dpg.collapsing_header(label="Tables"): with dpg.tree_node(label="Basic"): # basic usage of the table api with dpg.table(header_row=False): # use add_table_column to add columns to the table, # table columns use slot 0 dpg.add_table_column() dpg.add_table_column() dpg.add_table_column() # add_table_next_column will jump to the next row # once it reaches the end of the columns # table next column use slot 1 for i in range(4): with dpg.table_row(): for j in range(3): dpg.add_text(f"Row{i} Column{j}") with dpg.tree_node(label="Borders, background") as section: with dpg.table(header_row=False, row_background=True, borders_innerH=True, borders_outerH=True, borders_innerV=True, borders_outerV=True, delay_search=True) as table_id: dpg.add_table_column(label="Header 1") dpg.add_table_column(label="Header 2") dpg.add_table_column(label="Header 3") for i in range(5): with dpg.table_row(): for j in range(3): dpg.add_text(f"Row{i} Column{j}") _add_config_options(table_id, 2, "row_background", "borders_innerH", "borders_innerV", "borders_outerH", "borders_outerV", "header_row", before=table_id) with dpg.tree_node(label="Colors"): dpg.add_text("Highlighting Rows, Columns, Cells:") with dpg.table(header_row=False, row_background=True, delay_search=True) as table_id: dpg.add_table_column() dpg.add_table_column() dpg.add_table_column() dpg.add_table_column() dpg.add_table_column() dpg.add_table_column() for i in range(6): with dpg.table_row(): for j in range(6): dpg.add_text(f"R{i} C{j}") for i in range(6): dpg.highlight_table_row(table_id, i, [255, 0, 0, 100]) dpg.highlight_table_column(table_id, 4, [0, 255, 0, 100]) dpg.highlight_table_cell(table_id, 1, 1, [0, 0, 255, 100]) dpg.highlight_table_cell(table_id, 2, 1, [0, 0, 255, 100]) dpg.highlight_table_cell(table_id, 1, 2, [0, 0, 255, 100]) dpg.highlight_table_cell(table_id, 2, 2, [0, 0, 255, 100]) _add_config_options(table_id, 1, "row_background", before=table_id) dpg.add_text("Coloring rows:") with dpg.table(header_row=False, row_background=True, delay_search=True) as table_id: dpg.add_table_column() dpg.add_table_column() dpg.add_table_column() dpg.add_table_column() dpg.add_table_column() dpg.add_table_column() for i in range(6): with dpg.table_row(): for j in range(6): dpg.add_text(f"R{i} C{j}") dpg.highlight_table_cell(table_id, 1, 1, [0, 255, 0, 100]) dpg.highlight_table_cell(table_id, 2, 1, [0, 255, 0, 100]) dpg.highlight_table_cell(table_id, 1, 2, [0, 255, 0, 100]) dpg.highlight_table_cell(table_id, 2, 2, [0, 255, 0, 100]) for i in range(6): dpg.set_table_row_color(table_id, i, [255, 0, 0, i*255/8]) with dpg.tree_node(label="Resizable, stretch"): with dpg.table(header_row=False, resizable=True, delay_search=True, borders_outerH=True, borders_innerV=True, borders_outerV=True) as table_id: dpg.add_table_column(label="Header 1") dpg.add_table_column(label="Header 2") dpg.add_table_column(label="Header 3") for i in range(5): with dpg.table_row(): for j in range(3): dpg.add_text(f"Row{i} Column{j}") _add_config_options(table_id, 1, "borders_innerV", "borders_outerV", "resizable", before=table_id) with dpg.tree_node(label="Resizable, fixed"): dpg.add_text("Only available if scrollX/scrollY are disabled and stretch columns are not used") with dpg.table(header_row=False, policy=dpg.mvTable_SizingFixedFit, resizable=True, no_host_extendX=False, borders_innerV=True, delay_search=True, borders_outerV=True,borders_outerH=True) as table_id: dpg.add_table_column(label="Header 1") dpg.add_table_column(label="Header 2") dpg.add_table_column(label="Header 3") for i in range(5): with dpg.table_row(): for j in range(3): dpg.add_text(f"Row{i} Column{j}") _add_config_options(table_id, 1, "no_host_extendX", before=table_id) with dpg.tree_node(label="Resizable, mixed"): with dpg.table(header_row=True, policy=dpg.mvTable_SizingFixedFit, row_background=True, reorderable=True, resizable=True, no_host_extendX=False, hideable=True, borders_innerV=True, delay_search=True, borders_outerV=True, borders_innerH=True, borders_outerH=True): dpg.add_table_column(label="AAA", width_fixed=True) dpg.add_table_column(label="BBB", width_fixed=True) dpg.add_table_column(label="CCC", width_stretch=True, init_width_or_weight=0.0) for i in range(5): with dpg.table_row(): for j in range(3): if j == 2: dpg.add_text(f"Stretch {i}, {j}") else: dpg.add_text(f"Fixed {i}, {j}") with dpg.table(header_row=True, policy=dpg.mvTable_SizingFixedFit, row_background=True, reorderable=True, resizable=True, no_host_extendX=False, hideable=True, borders_innerV=True, delay_search=True, borders_outerV=True, borders_innerH=True, borders_outerH=True): dpg.add_table_column(label="AAA", width_fixed=True) dpg.add_table_column(label="BBB", width_fixed=True) dpg.add_table_column(label="CCC", width_stretch=True, init_width_or_weight=0.0) dpg.add_table_column(label="DDD", width_stretch=True, init_width_or_weight=0.0) for i in range(5): with dpg.table_row(): for j in range(4): if j == 2 or j == 3: dpg.add_text(f"Stretch {i},{j}") else: dpg.add_text(f"Fixed {i}, {j}") with dpg.tree_node(label="Columns Options"): with dpg.table(header_row=True, no_host_extendX=True, borders_innerH=True, borders_outerH=True, borders_innerV=True, borders_outerV=True, row_background=True, hideable=True, reorderable=True, resizable=True, sortable=True, policy=dpg.mvTable_SizingFixedFit, scrollX=True, delay_search=True, scrollY=True): c1 = dpg.add_table_column(label="One", default_sort=True) c2 = dpg.add_table_column(label="Two") c3 = dpg.add_table_column(label="Three", default_hide=True) for i in range(8): with dpg.table_row(): dpg.add_text("Indented One", indent=5*i) dpg.add_text("Hello Two") dpg.add_text("Hello Three") # options table with dpg.table(header_row=False, show=True): dpg.add_table_column() dpg.add_table_column() dpg.add_table_column() options = ( "default_hide", "default_sort", "width_stretch", "width_fixed", "no_resize", "no_reorder", "no_hide", "no_clip", "no_sort", "no_sort_ascending", "no_sort_descending", "no_header_width", "prefer_sort_ascending", "prefer_sort_descending") with dpg.table_row(): with dpg.table_cell(): dpg.add_text("One") _add_config_options(c1, 1, *options) with dpg.table_cell(): dpg.add_text("Two") _add_config_options(c2, 1, *options) with dpg.table_cell(): dpg.add_text("Three") _add_config_options(c3, 1, *options) with dpg.tree_node(label="Columns widths"): with dpg.table(header_row=True, resizable=True, borders_outerH=True, borders_innerH=True, borders_outerV=True, delay_search=True): dpg.add_table_column(label="One") dpg.add_table_column(label="Two") dpg.add_table_column(label="Three") with dpg.table_row(): for i in range(3): _text_id = dpg.add_text("(w: 0.0f)") with dpg.item_handler_registry(tag="__demo_item_reg4_"+str(i)): dpg.add_item_visible_handler(user_data = _text_id, callback=lambda s, a, u:dpg.set_value(u, "(w: " + str(dpg.get_item_state(u)["content_region_avail"][0]) + ")")) dpg.bind_item_handler_registry(_text_id, dpg.last_container()) for i in range(3): with dpg.table_row(): for j in range(3): dpg.add_text(f"Hello {i}, {j}") with dpg.table(header_row=False, delay_search=True) as table_id: dpg.add_table_column(width_fixed=True, init_width_or_weight=100) dpg.add_table_column(width_fixed=True, init_width_or_weight=200) dpg.add_table_column(width_fixed=True, init_width_or_weight=300) dpg.add_table_column(width_fixed=True, init_width_or_weight=400) with dpg.table_row(): for i in range(4): _text_id = dpg.add_text("(w: 0.0f)") with dpg.item_handler_registry(tag="__demo_item_reg5_"+str(i)): dpg.add_item_visible_handler(user_data = _text_id, callback=lambda s, a, u:dpg.set_value(u, "(w: " + str(dpg.get_item_state(u)["content_region_avail"][0]) + ")")) dpg.bind_item_handler_registry(_text_id, dpg.last_container()) for i in range(4): with dpg.table_row(): for j in range(4): dpg.add_text(f"Hello {i}, {j}") _add_config_options(table_id, 1, "no_keep_columns_visible", "borders_innerV", "borders_outerV", before=table_id) with dpg.tree_node(label="Row height"): with dpg.table(header_row=False, borders_outerH=True, borders_outerV=True, delay_search=True): dpg.add_table_column() for i in range(10): with dpg.table_row(height=i*5 + 25): dpg.add_text("height = " + str(i*5 + 25)) with dpg.tree_node(label="Padding"): with dpg.table(header_row=False, resizable=True, delay_search=True, hideable=True, reorderable=True, borders_outerV=True, borders_innerH=True) as table_id: dpg.add_table_column(label="One") dpg.add_table_column(label="Two") dpg.add_table_column(label="three") for i in range(5): with dpg.table_row(): for j in range(3): dpg.add_button(label=f"Hello {i}, {j}", width=-1) _add_config_options(table_id, 3, "pad_outerX", "no_pad_outerX", "no_pad_innerX", "borders_outerV", "borders_innerV", "header_row", before=table_id) with dpg.tree_node(label="Angled headers"): with dpg.table(header_row=True, resizable=True, delay_search=True, reorderable=True) as table_id: dpg.add_table_column(label="One", angled_header=True) dpg.add_table_column(label="Two", angled_header=True) dpg.add_table_column(label="three", angled_header=True) for i in range(5): with dpg.table_row(): for j in range(3): dpg.add_text(f"Hello {i}, {j}") with dpg.tree_node(label="Reorderable, hideable, with headers"): with dpg.table(header_row=True, resizable=True, delay_search=True, hideable=True, reorderable=True) as table_id: dpg.add_table_column(label="One") dpg.add_table_column(label="Two") dpg.add_table_column(label="three") for i in range(5): with dpg.table_row(): for j in range(3): dpg.add_text(f"Hello {i}, {j}") _add_config_options(table_id, 3, "hideable", "reorderable", "resizable", before=table_id) with dpg.tree_node(label="Outer Size"): with dpg.table(header_row=False, no_host_extendX=True, delay_search=True, borders_innerH=True, borders_outerH=True, borders_innerV=True, borders_outerV=True, context_menu_in_body=True, row_background=True, policy=dpg.mvTable_SizingFixedFit, height=150) as table_id: dpg.add_table_column(label="One") dpg.add_table_column(label="Two") dpg.add_table_column(label="three") for i in range(10): with dpg.table_row(): for j in range(3): dpg.add_text(f"Cell {i}, {j}") _add_config_options(table_id, 3, "no_host_extendX", "no_host_extendY", "resizable", before=table_id) dpg.add_text("Using explicit size:") with dpg.table(header_row=False, no_host_extendX=True, delay_search=True, borders_innerH=True, borders_outerH=True, borders_innerV=True, borders_outerV=True, context_menu_in_body=True, row_background=True, policy=dpg.mvTable_SizingFixedFit, height=300, width=300): dpg.add_table_column(label="One") dpg.add_table_column(label="Two") dpg.add_table_column(label="three") for i in range(6): with dpg.table_row(): for j in range(3): dpg.add_text(f"Cell {i}, {j}") with dpg.tree_node(label="Scrolling, Clipping"): # without clipping dpg.add_text("Without Clipper") with dpg.table(header_row=True, no_host_extendX=True, delay_search=True, borders_innerH=True, borders_outerH=True, borders_innerV=True, borders_outerV=True, context_menu_in_body=True, row_background=True, policy=dpg.mvTable_SizingFixedFit, height=300, scrollY=True): dpg.add_table_column(label="1") dpg.add_table_column(label="2") dpg.add_table_column(label="3") for i in range(25): with dpg.table_row(): dpg.add_input_int(label=" ", step=0) dpg.add_button(label=f"Cell {i}, 1") dpg.add_text(f"Cell {i}, 2") # with clipping dpg.add_text("Using Clipper") with dpg.table(header_row=True, no_host_extendX=True, delay_search=True, borders_innerH=True, borders_outerH=True, borders_innerV=True, borders_outerV=True, context_menu_in_body=True, row_background=True, policy=dpg.mvTable_SizingFixedFit, height=300, scrollY=True, clipper=True) as table_id: dpg.add_table_column(label="1") dpg.add_table_column(label="2") dpg.add_table_column(label="3") for i in range(25): with dpg.table_row(): dpg.add_input_int(label=" ", step=0) dpg.add_button(label=f"Cell {i}, 1") dpg.add_text(f"Cell {i}, 2") dpg.add_checkbox(label="resizable", before=table_id, default_value=True, user_data=table_id, callback=lambda sender, app_data, user_data:dpg.configure_item(user_data, resizable=app_data)) # Freezing rows/columns dpg.add_text("Freezing rows/columns") with dpg.table(header_row=True, borders_innerH=True, borders_outerH=True, borders_innerV=True, borders_outerV=True, row_background=True, height=300, freeze_rows=1, freeze_columns=1, scrollY=True, scrollX=True, policy=dpg.mvTable_SizingFixedFit, delay_search=True): dpg.add_table_column(label="1", width=50) dpg.add_table_column(label="2", width=50) dpg.add_table_column(label="3", width=50) dpg.add_table_column(label="4", width=50) dpg.add_table_column(label="5", width=50) dpg.add_table_column(label="6", width=50) dpg.add_table_column(label="7", width=50) for i in range(25): with dpg.table_row(): dpg.add_text(f"Cell {i}, 0") dpg.add_button(label=f"Cell {i}, 1") dpg.add_text(f"Cell {i}, 2") dpg.add_text(f"Cell {i}, 3") dpg.add_text(f"Cell {i}, 4") dpg.add_text(f"Cell {i}, 5") dpg.add_text(f"Cell {i}, 6") with dpg.tree_node(label="Filtering"): # with filtering dpg.add_text("Using Filter (column 3)") _filter_table_id = dpg.generate_uuid() dpg.add_input_text(label="Filter (inc, -exc)", user_data=_filter_table_id, callback=lambda s, a, u: dpg.set_value(u, dpg.get_value(s))) with dpg.table(header_row=True, no_host_extendX=True, delay_search=True, borders_innerH=True, borders_outerH=True, borders_innerV=True, borders_outerV=True, context_menu_in_body=True, row_background=True, policy=dpg.mvTable_SizingFixedFit, height=300, scrollY=True, tag=_filter_table_id) as table_id: dpg.add_table_column(label="1") dpg.add_table_column(label="2") dpg.add_table_column(label="3") for i in range(25): with dpg.table_row(filter_key=f"Cell {i}, 1"): dpg.add_input_int(label=" ", step=0) dpg.add_button(label=f"Cell {i}, 1") dpg.add_text(f"Cell {i}, 2") dpg.add_checkbox(label="resizable", before=table_id, default_value=True, user_data=table_id, callback=lambda sender, app_data, user_data:dpg.configure_item(user_data, resizable=app_data)) with dpg.tree_node(label="Sorting"): def _sort_callback(sender, sort_specs): # sort_specs scenarios: # 1. no sorting -> sort_specs == None # 2. single sorting -> sort_specs == [[column_id, direction]] # 3. multi sorting -> sort_specs == [[column_id, direction], [column_id, direction], ...] # # notes: # 1. direction is ascending if == 1 # 2. direction is ascending if == -1 # no sorting case if sort_specs is None: return rows = dpg.get_item_children(sender, 1) # create a list that can be sorted based on first cell # value, keeping track of row and value used to sort sortable_list = [] for row in rows: first_cell = dpg.get_item_children(row, 1)[0] sortable_list.append([row, dpg.get_value(first_cell)]) def _sorter(e): return e[1] sortable_list.sort(key=_sorter, reverse=sort_specs[0][1] < 0) # create list of just sorted row ids new_order = [] for pair in sortable_list: new_order.append(pair[0]) dpg.reorder_items(sender, 1, new_order) with dpg.table(header_row=True, no_host_extendX=True, borders_innerH=True, borders_outerH=True, borders_innerV=True, borders_outerV=True, context_menu_in_body=True, row_background=True, policy=dpg.mvTable_SizingFixedFit, height=500, sortable=True, callback=_sort_callback, scrollY=True, delay_search=True, tag="__demo_sorting_table"): dpg.add_table_column(label="One") dpg.add_table_column(label="Two", no_sort=True) dpg.add_table_column(label="Three", no_sort=True) for i in range(25): with dpg.table_row(): dpg.add_input_int(label=" ", step=0, default_value=i) dpg.add_text(f"Cell {i}, 1") dpg.add_checkbox(label=f"Cell {i}, 2") #dpg.add_checkbox(label="sort_multi", before=table_id, user_data=table_id, callback=lambda sender, app_data, user_data:dpg.configure_item(user_data, sort_multi=app_data)) dpg.add_checkbox(label="sort_tristate", before="__demo_sorting_table", callback=lambda sender, app_data, user_data:dpg.configure_item("__demo_sorting_table", sort_tristate=app_data)) with dpg.tree_node(label="Selecting rows"): with dpg.theme() as table_theme: with dpg.theme_component(dpg.mvTable): dpg.add_theme_color(dpg.mvThemeCol_HeaderActive, (0, 0, 0, 0), category=dpg.mvThemeCat_Core) dpg.add_theme_color(dpg.mvThemeCol_Header, (0, 0, 0, 0), category=dpg.mvThemeCat_Core) def clb_selectable(sender, app_data, user_data): print(f"Row {user_data}") with dpg.table(header_row=True) as table_sel_rows: dpg.add_table_column(label="First") dpg.add_table_column(label="Second") dpg.add_table_column(label="Third") for i in range(10): with dpg.table_row(): for j in range(3): dpg.add_selectable(label=f"Row{i} Column{j}", span_columns=True, callback=clb_selectable, user_data=i) dpg.bind_item_theme(table_sel_rows, table_theme) with dpg.tree_node(label="Selecting cells"): with dpg.theme() as table_theme: with dpg.theme_component(dpg.mvTable): dpg.add_theme_color(dpg.mvThemeCol_HeaderActive, (0, 0, 0, 0), category=dpg.mvThemeCat_Core) dpg.add_theme_color(dpg.mvThemeCol_Header, (0, 0, 0, 0), category=dpg.mvThemeCat_Core) def clb_selectable(sender, app_data, user_data): print(f"Row {user_data}") with dpg.table(header_row=True) as table_sel_cols: dpg.add_table_column(label="First") dpg.add_table_column(label="Second") dpg.add_table_column(label="Third") for i in range(10): with dpg.table_row(): for j in range(3): dpg.add_selectable(label=f"Row{i} Column{j}", callback=clb_selectable, user_data=(i,j)) dpg.bind_item_theme(table_sel_cols, table_theme) with dpg.tree_node(label="Sizing Policy"): def callback(sender, value, user_data): if user_data[8] == "resizable": for i in range(8): dpg.configure_item(user_data[i], resizable=value) elif user_data[8] == "no_host_extendX": for i in range(8): dpg.configure_item(user_data[i], no_host_extendX=value) elif user_data[8] == "policy": if value == "mvTable_SizingFixedFit": dpg.configure_item(user_data[user_data[9]], policy=dpg.mvTable_SizingFixedFit) dpg.configure_item(user_data[user_data[9]+1], policy=dpg.mvTable_SizingFixedFit) elif value == "mvTable_SizingFixedSame": dpg.configure_item(user_data[user_data[9]], policy=dpg.mvTable_SizingFixedSame) dpg.configure_item(user_data[user_data[9]+1], policy=dpg.mvTable_SizingFixedSame) elif value == "mvTable_SizingStretchProp": dpg.configure_item(user_data[user_data[9]], policy=dpg.mvTable_SizingStretchProp) dpg.configure_item(user_data[user_data[9]+1], policy=dpg.mvTable_SizingStretchProp) elif value == "mvTable_SizingStretchSame": dpg.configure_item(user_data[user_data[9]], policy=dpg.mvTable_SizingStretchSame) dpg.configure_item(user_data[user_data[9]+1], policy=dpg.mvTable_SizingStretchSame) def create_table_set(policy): with dpg.table(header_row=False, policy=policy, delay_search=True, borders_innerH=True, borders_outerH=True, borders_innerV=True, borders_outerV=True, row_background=True) as table_id1: dpg.add_table_column() dpg.add_table_column() dpg.add_table_column() for i in range(8): with dpg.table_row(): dpg.add_text("Oh dear") dpg.add_text("Oh dear") dpg.add_text("Oh dear") with dpg.table(header_row=False, policy=policy, borders_innerH=True, borders_outerH=True, borders_innerV=False, borders_outerV=True, row_background=True) as table_id2: dpg.add_table_column() dpg.add_table_column() dpg.add_table_column() for i in range(3): with dpg.table_row(): dpg.add_text("AAAA") dpg.add_text("BBBBBBBB") dpg.add_text("CCCCCCCCCCCC") return table_id1, table_id2 table_id1, table_id12 = create_table_set(dpg.mvTable_SizingFixedFit) table_id2, table_id22 = create_table_set(dpg.mvTable_SizingFixedSame) table_id3, table_id32 = create_table_set(dpg.mvTable_SizingStretchProp) table_id4, table_id42 = create_table_set(dpg.mvTable_SizingStretchSame) user_data = [table_id1, table_id12, table_id2, table_id22, table_id3, table_id32, table_id4, table_id42] sizing_options = ("mvTable_SizingFixedFit", "mvTable_SizingFixedSame", "mvTable_SizingStretchProp", "mvTable_SizingStretchSame") combo1 = dpg.add_combo(sizing_options, label="Sizing Policy", default_value=sizing_options[0], before=table_id1, user_data=user_data + ["policy", 0], callback=callback) dpg.add_combo(sizing_options, label="Sizing Policy", default_value=sizing_options[1], before=table_id2, user_data=user_data + ["policy", 2], callback=callback) dpg.add_combo(sizing_options, label="Sizing Policy", default_value=sizing_options[2], before=table_id3, user_data=user_data + ["policy", 4], callback=callback) dpg.add_combo(sizing_options, label="Sizing Policy", default_value=sizing_options[3], before=table_id4, user_data=user_data + ["policy", 6], callback=callback) dpg.add_checkbox(label="resizable", before=combo1, user_data=user_data + ["resizable"], callback=callback) dpg.add_checkbox(label="no_host_extendX", before=combo1, user_data=user_data + ["no_host_extendX"], callback=callback) with dpg.collapsing_header(label="Plots"): sindatax = [] sindatay = [] cosdatay = [] for i in range(100): sindatax.append(i/100) sindatay.append(0.5 + 0.5*sin(50*i/100)) cosdatay.append(0.5 + 0.75*cos(50*i/100)) with dpg.tab_bar(): with dpg.tab(label="Series"): with dpg.tree_node(label="Line Series"): # create plot with dpg.plot(label="Line Series", height=400, width=-1): # optionally create legend dpg.add_plot_legend() # REQUIRED: create x and y axes dpg.add_plot_axis(dpg.mvXAxis, label="x") with dpg.plot_axis(dpg.mvYAxis, label="y"): # series belong to a y axis dpg.add_line_series(sindatax, sindatay, label="0.5 + 0.5 * sin(x)") with dpg.tree_node(label="Filled Line Series"): dpg.add_checkbox(label="fill", tag="fill_series_cb", default_value=False, callback=lambda: dpg.configure_item("filled_line_series", shaded=dpg.get_value("fill_series_cb"))) dpg.add_checkbox(label="segment", tag="segment_series_cb", default_value=False, callback=lambda: dpg.configure_item("filled_line_series", segments=dpg.get_value("segment_series_cb"))) with dpg.plot(label="Filled Line Plot", height=400, width=-1): dpg.add_plot_legend() dpg.add_plot_axis(dpg.mvXAxis, label="x") with dpg.plot_axis(dpg.mvYAxis, label="y"): dpg.add_line_series(sindatax, sindatay, tag="filled_line_series", label="0.5 + 0.5 * sin(x)") with dpg.tree_node(label="Text point"): # create plot with dpg.plot(label="Text point", height=400, width=-1): # optionally create legend dpg.add_plot_legend() # REQUIRED: create x and y axes dpg.add_plot_axis(dpg.mvXAxis, label="x") with dpg.plot_axis(dpg.mvYAxis, label="y"): # series belong to a y axis dpg.add_text_point(2., 1.5, label="Text point label") with dpg.tree_node(label="Shade Series"): std_alpha = 0.25 def _cb_alpha(_, app_data): with dpg.theme() as alpha_theme: with dpg.theme_component(0): dpg.add_theme_style(dpg.mvPlotStyleVar_FillAlpha, app_data, category=dpg.mvThemeCat_Plots) dpg.bind_item_theme("shaded_plot_1", alpha_theme) dpg.add_drag_float(min_value=0, max_value=1, callback=_cb_alpha, speed=0.01, default_value=std_alpha) with dpg.theme() as alpha_theme: with dpg.theme_component(0): dpg.add_theme_style(dpg.mvPlotStyleVar_FillAlpha, std_alpha, category=dpg.mvThemeCat_Plots) with dpg.plot(label="Shaded Plot", tag="shaded_plot_1", height=400, width=-1): xs = [] ys = [] ys1 = [] ys2 = [] ys3 = [] ys4 = [] random.seed(0) for i in range(1001): xs.append(i * 0.001) ys.append(0.25 + 0.25 * sin(25 * xs[i]) * sin(5 * xs[i]) + random.uniform(-0.01, 0.01)) ys1.append(ys[i] + random.uniform(0.1, 0.12)) ys2.append(ys[i] - random.uniform(0.1, 0.12)) ys3.append(0.75 + 0.2 * sin(25 * xs[i])) ys4.append(0.75 + 0.1 * cos(25 * xs[i])) dpg.add_plot_axis(dpg.mvXAxis, label="x") with dpg.plot_axis(dpg.mvYAxis, label="y"): dpg.add_shade_series(xs, ys1, y2=ys2, label="Uncertain data") dpg.add_line_series(xs, ys, label="Uncertain data") dpg.add_shade_series(xs, ys3, y2=ys4, label="Overlapping") dpg.add_line_series(xs, ys3, label="Overlapping") dpg.add_line_series(xs, ys4, label="Overlapping") dpg.bind_item_theme("shaded_plot_1", alpha_theme) stock_datax = [] stock_datay2 = [] stock_data1 = [] stock_data2 = [] stock_data3 = [] stock_data4 = [] stock_data5 = [] for i in range(100): stock_datax.append(i) stock_datay2.append(0) stock_data1.append(400 + 50*abs(random.random())) stock_data2.append(275 + 75*abs(random.random())) stock_data3.append(150 + 75*abs(random.random())) stock_data4.append(500 + 75*abs(random.random())) stock_data5.append(600 + 75*abs(random.random())) with dpg.theme(tag="stock_theme1"): with dpg.theme_component(0): dpg.add_theme_color(dpg.mvPlotCol_Line, (0, 0, 255), category=dpg.mvThemeCat_Plots) dpg.add_theme_color(dpg.mvPlotCol_Fill, (0, 0, 255, 64), category=dpg.mvThemeCat_Plots) with dpg.theme(tag="stock_theme2"): with dpg.theme_component(0): dpg.add_theme_color(dpg.mvPlotCol_Line, (255, 0, 0), category=dpg.mvThemeCat_Plots) dpg.add_theme_color(dpg.mvPlotCol_Fill, (255, 0, 0, 64), category=dpg.mvThemeCat_Plots) with dpg.theme(tag="stock_theme3"): with dpg.theme_component(0): dpg.add_theme_color(dpg.mvPlotCol_Line, (0, 255, 0), category=dpg.mvThemeCat_Plots) dpg.add_theme_color(dpg.mvPlotCol_Fill, (0, 255, 0, 64), category=dpg.mvThemeCat_Plots) with dpg.theme(tag="stock_theme4"): with dpg.theme_component(0): dpg.add_theme_color(dpg.mvPlotCol_Fill, (255, 255, 100, 64), category=dpg.mvThemeCat_Plots) with dpg.plot(label="Stock Prices", height=400, width=-1): dpg.add_plot_legend() xaxis = dpg.add_plot_axis(dpg.mvXAxis, label="Days") with dpg.plot_axis(dpg.mvYAxis, label="Price"): dpg.add_line_series(stock_datax, stock_data1, label="Stock 1") dpg.bind_item_theme(dpg.last_item(), "stock_theme1") dpg.add_line_series(stock_datax, stock_data2, label="Stock 2") dpg.bind_item_theme(dpg.last_item(), "stock_theme2") dpg.add_line_series(stock_datax, stock_data3, label="Stock 3") dpg.bind_item_theme(dpg.last_item(), "stock_theme3") dpg.add_shade_series(stock_datax, stock_data1, label="Stock 1") dpg.bind_item_theme(dpg.last_item(), "stock_theme1") dpg.add_shade_series(stock_datax, stock_data2, label="Stock 2") dpg.bind_item_theme(dpg.last_item(), "stock_theme2") dpg.add_shade_series(stock_datax, stock_data3, label="Stock 3", y2=stock_datay2) dpg.bind_item_theme(dpg.last_item(), "stock_theme3") dpg.add_shade_series(stock_datax, stock_data5, y2=stock_data4, label="Shade between lines") dpg.bind_item_theme(dpg.last_item(), "stock_theme4") dpg.fit_axis_data(dpg.top_container_stack()) dpg.fit_axis_data(xaxis) with dpg.tree_node(label="Scatter Series"): with dpg.plot(label="Scatter Series", height=400, width=-1): dpg.add_plot_legend() dpg.add_plot_axis(dpg.mvXAxis, label="x") with dpg.plot_axis(dpg.mvYAxis, label="y"): dpg.add_scatter_series(sindatax, sindatay, label="0.5 + 0.5 * sin(x)") with dpg.tree_node(label="Stair Series"): dpg.add_checkbox(label="pre-step", tag="pre_step_cb", default_value=False, callback=lambda: dpg.configure_item("stair_series", pre_step=dpg.get_value("pre_step_cb"))) dpg.add_checkbox(label="filled", tag="filled_stairs_cb", default_value=False, callback=lambda: dpg.configure_item("stair_series", shaded=dpg.get_value("filled_stairs_cb"))) with dpg.plot(label="Stair Plot", height=400, width=-1): dpg.add_plot_legend() dpg.add_plot_axis(dpg.mvXAxis, label="x") with dpg.plot_axis(dpg.mvYAxis, label="y"): dpg.add_stair_series(sindatax, sindatay, tag="stair_series", label="0.5 + 0.5 * sin(x)") with dpg.tree_node(label="Bar Series"): dpg.add_checkbox(label="horizontal", tag="horizontal_bar_cb", default_value=False, callback=lambda: dpg.configure_item("bar_series", horizontal=dpg.get_value("horizontal_bar_cb"))) with dpg.plot(label="Bar Series", height=400, width=-1): dpg.add_plot_legend() # create x axis dpg.add_plot_axis(dpg.mvXAxis, label="Student", no_gridlines=True) dpg.set_axis_limits(dpg.last_item(), 9, 33) dpg.set_axis_ticks(dpg.last_item(), (("S1", 11), ("S2", 21), ("S3", 31))) dpg.add_plot_axis(dpg.mvXAxis2, label="hor_value", no_gridlines=True) dpg.set_axis_limits(dpg.last_item(), 0, 110) # create y axis with dpg.plot_axis(dpg.mvYAxis, label="Score"): dpg.set_axis_limits(dpg.last_item(), 0, 110) dpg.add_bar_series([10, 20, 30], [100, 75, 90], tag="bar_series", label="Final Exam", weight=1) dpg.add_bar_series([11, 21, 31], [83, 75, 72], label="Midterm Exam", weight=1) dpg.add_bar_series([12, 22, 32], [42, 68, 23], label="Course Grade", weight=1) with dpg.tree_node(label="Bar Group Series"): limits_group_series = [-0.5, 9.5] def set_horizontal(sender, app_data, user_data): dpg.configure_item("bar_group_series", horizontal=app_data) if app_data: dpg.set_axis_limits("yaxis_bar_group", *limits_group_series) dpg.set_axis_ticks("yaxis_bar_group", glabels) dpg.reset_axis_ticks("xaxis_bar_group") dpg.set_axis_limits_auto("xaxis_bar_group") else: dpg.set_axis_limits("xaxis_bar_group", *limits_group_series) dpg.set_axis_ticks("xaxis_bar_group", glabels) dpg.reset_axis_ticks("yaxis_bar_group") dpg.set_axis_limits_auto("yaxis_bar_group") def _callback_stacked(sender, app_data, user_data): dpg.configure_item("bar_group_series", stacked=app_data) is_horizontal = dpg.get_item_configuration("bar_group_series")["horizontal"] if is_horizontal: dpg.set_axis_limits_auto("xaxis_bar_group") else: dpg.set_axis_limits_auto("yaxis_bar_group") dpg.add_checkbox(label="Horizontal", default_value=False, callback=set_horizontal) dpg.add_checkbox(label="Stacked", default_value=False, callback=_callback_stacked) dpg.add_slider_float(label="Bar Width", default_value=0.67, max_value=1.0, min_value=0.1, callback=lambda _, val: dpg.configure_item("bar_group_series", group_width=val)) with dpg.plot(label="Bar Group Series", height=400, width=-1): dpg.add_plot_legend() values_group_series = [83, 67, 23, 89, 83, 78, 91, 82, 85, 90, 80, 62, 56, 99, 55, 78, 88, 78, 90, 100, 80, 69, 52, 92, 72, 78, 75, 76, 89, 95] ilabels = ["Midterm Exam","Final Exam","Course Grade"] glabels = (("S1",0), ("S2",1), ("S3",2), ("S4",3), ("S5",4), ("S6",5), ("S7",6), ("S8",7), ("S9",8), ("S10",9)) groups_c = 3 # create x axis dpg.add_plot_axis(dpg.mvXAxis, label="Student", tag="xaxis_bar_group", no_gridlines=True, auto_fit=True) dpg.set_axis_limits(dpg.last_item(), *limits_group_series) dpg.set_axis_ticks(dpg.last_item(), glabels) # create y axis with dpg.plot_axis(dpg.mvYAxis, label="Score", tag="yaxis_bar_group", auto_fit=True): dpg.set_axis_limits(dpg.last_item(), 0, 110) dpg.add_bar_group_series(values=values_group_series, label_ids=ilabels, group_size=groups_c, tag="bar_group_series", label="Final Exam") with dpg.tree_node(label="Bar Stacks"): politicians = (("Trump", 0), ("Bachman", 1), ("Cruz", 2), ("Gingrich", 3), ("Palin", 4), ("Santorum", 5), ("Walker", 6), ("Perry", 7), ("Ryan", 8), ("McCain", 9), ("Rubio", 10), ("Romney", 11), ("Rand Paul", 12), ("Christie", 13), ("Biden", 14), ("Kasich", 15), ("Sanders", 16), ("J Bush", 17), ("H Clinton", 18), ("Obama", 19)) data_reg = [18,26,7,14,10,8,6,11,4,4,3,8,6,8,6,5,0,3,1,2, # Pants on Fire 43,36,30,21,30,27,25,17,11,22,15,16,16,17,12,12,14,6,13,12, # False 16,13,28,22,15,21,15,18,30,17,24,18,13,10,14,15,17,22,14,12, # Mostly False 17,10,13,25,12,22,19,26,23,17,22,27,20,26,29,17,18,22,21,27, # Half True 5,7,16,10,10,12,23,13,17,20,22,16,23,19,20,26,36,29,27,26, # Mostly True 1,8,6,8,23,10,12,15,15,20,14,15,22,20,19,25,15,18,24,21] # True labels_reg = ["Pants on Fire","False","Mostly False","Half True","Mostly True","True"] data_div = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, # Pants on Fire (dummy, to order legend logically) 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, # False (dummy, to order legend logically) 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, # Mostly False (dummy, to order legend logically) -16,-13,-28,-22,-15,-21,-15,-18,-30,-17,-24,-18,-13,-10,-14,-15,-17,-22,-14,-12, # Mostly False -43,-36,-30,-21,-30,-27,-25,-17,-11,-22,-15,-16,-16,-17,-12,-12,-14,-6,-13,-12, # False -18,-26,-7,-14,-10,-8,-6,-11,-4,-4,-3,-8,-6,-8,-6,-5,0,-3,-1,-2, # Pants on Fire 17,10,13,25,12,22,19,26,23,17,22,27,20,26,29,17,18,22,21,27, # Half True 5,7,16,10,10,12,23,13,17,20,22,16,23,19,20,26,36,29,27,26, # Mostly True 1,8,6,8,23,10,12,15,15,20,14,15,22,20,19,25,15,18,24,21] # True labels_div = ["Pants on Fire","False","Mostly False","Mostly False", "False","Pants on Fire","Half True","Mostly True","True"] def divergent_stack_cb(sender, app_data, user_data): if app_data: dpg.configure_item("divergent_stack_series", values=data_div, label_ids=labels_div, group_size=len(labels_reg), group_width=0.75, shift=0, stacked=True, horizontal=True) else: dpg.configure_item("divergent_stack_series", values=data_reg, label_ids=labels_reg, group_size=len(labels_div), group_width=0.75, shift=0, stacked=True, horizontal=True) dpg.add_checkbox(label="Divergent", tag="divergent_stack_cb", default_value=True, callback=divergent_stack_cb) with dpg.plot(label="PolitiFact: Who Lies More?", height=400, width=-1): dpg.add_plot_legend() # create x axis dpg.add_plot_axis(dpg.mvXAxis, no_gridlines=True) # create y axis with dpg.plot_axis(dpg.mvYAxis) as yaxis: dpg.set_axis_ticks(yaxis, politicians) dpg.set_axis_limits(yaxis, -0.5, 19.5) dpg.add_bar_group_series(tag="divergent_stack_series", values=data_div, label_ids=labels_div, group_size=len(labels_div), group_width=0.75, shift=0, stacked=True, horizontal=True) # dpg.add_bar_group_series(values=data_reg, label_ids=labels_reg, # group_size=20, group_width=0.75, shift=0, stacked=True, horizontal=True) with dpg.tree_node(label="Error Series"): error1_x = [1, 2, 3, 4, 5] error1_y = [1, 2, 5, 3, 4] error1_neg = [0.2, 0.4, 0.2, 0.6, 0.4] error1_pos = [0.4, 0.2, 0.4, 0.8, 0.6] error2_x = [1, 2, 3, 4, 5] error2_y = [8, 8, 9, 7, 8] error2_neg = [0.2, 0.4, 0.2, 0.6, 0.4] error2_pos = [0.4, 0.2, 0.4, 0.8, 0.6] dpg.add_text("Anti-aliasing can be enabled from the plot's context menu (see Help).", bullet=True) with dpg.plot(label="Error Series", height=400, width=-1): dpg.add_plot_legend() xaxis = dpg.add_plot_axis(dpg.mvXAxis, label="x") with dpg.plot_axis(dpg.mvYAxis, label="y"): dpg.add_bar_series(error1_x, error1_y, label="Bar", weight=0.25) dpg.add_error_series(error1_x, error1_y, error1_neg, error1_pos, label="Bar") dpg.add_line_series(error2_x, error2_y, label="Line") dpg.add_error_series(error2_x, error2_y, error2_neg, error2_pos, label="Line") dpg.fit_axis_data(dpg.top_container_stack()) dpg.fit_axis_data(xaxis) with dpg.tree_node(label="Stem Series"): with dpg.theme(tag="stem_theme1"): with dpg.theme_component(0): dpg.add_theme_color(dpg.mvPlotCol_Line, (0, 255, 0), category=dpg.mvThemeCat_Plots) dpg.add_theme_style(dpg.mvPlotStyleVar_Marker, dpg.mvPlotMarker_Diamond, category=dpg.mvThemeCat_Plots) with dpg.plot(label="Stem Series", height=400, width=-1): dpg.add_plot_legend() dpg.add_plot_axis(dpg.mvXAxis, label="x") with dpg.plot_axis(dpg.mvYAxis, label="y"): dpg.add_stem_series(sindatax, sindatay, label="0.5 + 0.5 * sin(x)") dpg.add_stem_series(sindatax, cosdatay, label="0.5 + 0.75 * cos(x)") dpg.bind_item_theme(dpg.last_item(), "stem_theme1") with dpg.tree_node(label="Infinite Lines"): infinite_x_data = (3, 5, 6, 7) infinite_y_data = (3, 5, 6, 7) with dpg.plot(label="Infinite Lines", height=400, width=-1): dpg.add_plot_legend() xaxis = dpg.add_plot_axis(dpg.mvXAxis, label="x") with dpg.plot_axis(dpg.mvYAxis, label="y"): dpg.add_inf_line_series(infinite_x_data, label="vertical") dpg.add_inf_line_series(infinite_y_data, label="horizontal", horizontal=True) dpg.fit_axis_data(dpg.top_container_stack()) dpg.fit_axis_data(xaxis) with dpg.tree_node(label="Pie Charts"): with dpg.group(horizontal=True): # create plot 1 with dpg.plot(no_title=True, no_mouse_pos=True, width=250, height=250): # create legend dpg.add_plot_legend() # create x axis dpg.add_plot_axis(dpg.mvXAxis, label="", no_gridlines=True, no_tick_marks=True, no_tick_labels=True) dpg.set_axis_limits(dpg.last_item(), 0, 1) # create y axis with dpg.plot_axis(dpg.mvYAxis, label="", no_gridlines=True, no_tick_marks=True, no_tick_labels=True): dpg.set_axis_limits(dpg.last_item(), 0, 1) dpg.add_pie_series(0.5, 0.5, 0.5, [0.25, 0.30, 0.30], ["fish", "cow", "chicken"]) # plot 2 with dpg.plot(no_title=True, no_mouse_pos=True, width=250, height=250): # create legend dpg.add_plot_legend() # create x axis dpg.add_plot_axis(dpg.mvXAxis, label="", no_gridlines=True, no_tick_marks=True, no_tick_labels=True) dpg.set_axis_limits(dpg.last_item(), 0, 1) # create y axis with dpg.plot_axis(dpg.mvYAxis, label="", no_gridlines=True, no_tick_marks=True, no_tick_labels=True): dpg.set_axis_limits(dpg.last_item(), 0, 1) dpg.add_pie_series(0.5, 0.5, 0.5, [1, 1, 2, 3, 5], ["A", "B", "C", "D", "E"], normalize=True, format="%.0f") with dpg.tree_node(label="Heatmaps"): dpg.add_checkbox(label="major col", tag="major_col_heat_cb", default_value=False, callback=lambda _, a: dpg.configure_item("heat_series", col_major=a)) values = (0.8, 2.4, 2.5, 3.9, 0.0, 4.0, 0.0, 2.4, 0.0, 4.0, 1.0, 2.7, 0.0, 0.0, 1.1, 2.4, 0.8, 4.3, 1.9, 4.4, 0.0, 0.6, 0.0, 0.3, 0.0, 3.1, 0.0, 0.0, 0.7, 1.7, 0.6, 2.6, 2.2, 6.2, 0.0, 1.3, 1.2, 0.0, 0.0, 0.0, 3.2, 5.1, 0.1, 2.0, 0.0, 1.4, 0.0, 1.9, 6.3) with dpg.group(horizontal=True): dpg.add_colormap_scale(min_scale=0, max_scale=10, height=400) with dpg.plot(label="Heat Series", no_mouse_pos=True, height=400, width=-1): dpg.add_plot_axis(dpg.mvXAxis, label="x", lock_min=True, lock_max=True, no_gridlines=True, no_tick_marks=True) with dpg.plot_axis(dpg.mvYAxis, label="y", no_gridlines=True, no_tick_marks=True, lock_min=True, lock_max=True): dpg.add_heat_series(values, 7, 7, tag="heat_series",scale_min=0, scale_max=6.3) with dpg.tree_node(label="Histogram Series"): x_data = [] for i in range(10000): x = random.randrange(1, 11) x_data.append(x) def update_density(user_data, app_data, other_data): dpg.configure_item("histogram_series", density=app_data) dpg.add_checkbox(label="density", tag="density_histograms_cb", default_value=False, callback=update_density) dpg.add_checkbox(label="cumulative", tag="cumulative_histograms_cb", default_value=False, callback=lambda: dpg.configure_item("histogram_series", cumulative=dpg.get_value("cumulative_histograms_cb"))) with dpg.plot(label="Histogram Plot", height=400, width=-1): dpg.add_plot_legend() xaxis = dpg.add_plot_axis(dpg.mvXAxis, label="x") dpg.set_axis_limits(xaxis, 1, 10) dpg.set_axis_ticks(xaxis, (("S1", 1), ("S2", 2), ("S3", 3), ("S4", 4), ("S5", 5), ("S6", 6), ("S7", 7), ("S8", 8), ("S9", 9), ("S10", 10))) with dpg.plot_axis(dpg.mvYAxis, label="y axis", tag="yaxis_histogram", auto_fit=True) as yaxis: dpg.add_histogram_series(x_data, tag="histogram_series", label="histogram") dpg.fit_axis_data(xaxis) with dpg.tree_node(label="Histogram 2D Series"): def update_count(_, app_data): global count_2d_histogram count_2d_histogram = app_data x_dist = [random.gauss(1, 2) for _ in range(count_2d_histogram)] y_dist = [random.gauss(1, 1) for _ in range(count_2d_histogram)] max_count = max(*x_dist, *y_dist) dpg.configure_item("histogram_2d_series", x=x_dist, y=y_dist) dpg.configure_item("2d_hist_colormap_scale", max_scale=max_count) def update_bins(_, app_data): global xybin_2d_histogram xybin_2d_histogram = app_data dpg.configure_item("histogram_2d_series", xbins=app_data[0], ybins=app_data[1]) def _update_density(_, app_data): dpg.configure_item("histogram_2d_series", density=app_data) # TODO: Find a way to access max_count 2d histogram dpg.configure_item("2d_hist_colormap_scale", max_scale=1.0 if app_data else max_count, label="Density" if app_data else "Count") dpg.add_slider_int(label="Count", min_value=100, max_value=100000, callback=update_count, default_value=count_2d_histogram, tag="count_histograms_2d", width=300) with dpg.group(horizontal=True): dpg.add_slider_intx(label="Bins", min_value=1, max_value=500, tag="bins", size=2, callback=update_bins, width=300, default_value=xybin_2d_histogram) dpg.add_checkbox(label="density", tag="density_histograms_2d_cb", default_value=False, callback=_update_density) max_count = 0.0 with dpg.group(horizontal=True, tag="histogram_2d_plot_group"): with dpg.plot(label="Histogram 2D Plot", tag="2d_histogram_plot", height=400, width=650): x_dist = [random.gauss(1, 2) for _ in range(count_2d_histogram)] y_dist = [random.gauss(1, 1) for _ in range(count_2d_histogram)] max_count = float(max(*x_dist, *y_dist)) x_axis = dpg.add_plot_axis(dpg.mvXAxis, label="x", auto_fit=True, foreground_grid=True) dpg.set_axis_limits(dpg.last_item(), -6, 6) with dpg.plot_axis(dpg.mvYAxis, label="y", auto_fit=True, foreground_grid=True): dpg.set_axis_limits(dpg.last_item(), -6, 6) dpg.add_2d_histogram_series(x_dist, y_dist, tag="histogram_2d_series", label="histogram", xbins=xybin_2d_histogram[0], ybins=xybin_2d_histogram[1], xmax_range=6, ymax_range=6, ymin_range=-6, xmin_range=-6) dpg.add_colormap_scale(tag="2d_hist_colormap_scale", label="Count", colormap=dpg.mvPlotColormap_Hot, min_scale=0.0, max_scale=max_count, height=400) dpg.bind_colormap("2d_histogram_plot", dpg.mvPlotColormap_Hot) with dpg.tree_node(label="Digital Plots"): dpg.add_text(default_value="Digital plots do not respond to Y drag and zoom, so that", bullet=True) dpg.add_text(default_value="you can drag analog plots over the rising/falling digital edge.", indent=20) paused = False data_digital = [[], []] data_analog = [[], []] show_digital = [True, False] show_analog = [True, False] def change_val(arr, ind, val): arr[ind] = val with dpg.group(horizontal=True): dpg.add_checkbox(label="digital_0", callback=lambda s, a: change_val(show_digital, 0, a), default_value=True) dpg.add_checkbox(label="digital_1", callback=lambda s, a: change_val(show_digital, 1, a), default_value=False) dpg.add_checkbox(label="analog_0", callback=lambda s, a: change_val(show_analog, 0, a), default_value=True) dpg.add_checkbox(label="analog_1", callback=lambda s, a: change_val(show_analog, 1, a), default_value=False) with dpg.plot(tag="_demo_digital_plot", width=500): # TODO: better handling of show/hide (more consistency between checkboxes and legend) dpg.add_plot_axis(dpg.mvXAxis, label="x", tag="x_axis_digital") dpg.set_axis_limits(dpg.last_item(), -10, 0) with dpg.plot_axis(dpg.mvYAxis, label="y"): dpg.set_axis_limits(dpg.last_item(), -2, 1.5) dpg.add_digital_series([], [], label="digital_0", tag="digital_0") dpg.add_digital_series([], [], label="digital_1", tag="digital_1") dpg.add_line_series([], [], label="analog_0", tag="analog_0") dpg.add_line_series([], [], label="analog_1", tag="analog_1") def _update_plot(): global t_digital_plot if not paused: t_digital_plot += dpg.get_delta_time() dpg.set_axis_limits('x_axis_digital', t_digital_plot - 10, t_digital_plot) if show_digital[0]: data_digital[0].append([t_digital_plot, 1 if sin(t_digital_plot) > 0.45 else 0]) dpg.set_value("digital_0", [*zip(*data_digital[0])]) if show_digital[1]: data_digital[1].append([t_digital_plot, 1 if sin(t_digital_plot) < 0.45 else 0]) dpg.set_value("digital_1", [*zip(*data_digital[1])]) if show_analog[0]: data_analog[0].append([t_digital_plot, sin(t_digital_plot)]) dpg.set_value("analog_0", [*zip(*data_analog[0])]) if show_analog[1]: data_analog[1].append([t_digital_plot, cos(t_digital_plot)]) dpg.set_value("analog_1", [*zip(*data_analog[1])]) with dpg.item_handler_registry(tag="__demo_digital_plot_ref"): dpg.add_item_visible_handler(callback=_update_plot) dpg.bind_item_handler_registry("_demo_digital_plot", dpg.last_container()) with dpg.tree_node(label="Image Series"): with dpg.plot(label="Image Plot", height=400, width=-1): dpg.add_plot_legend() xaxis = dpg.add_plot_axis(dpg.mvXAxis, label="x") with dpg.plot_axis(dpg.mvYAxis, label="y axis"): dpg.add_image_series(2, [300, 300], [400, 400], label="font atlas") dpg.add_image_series("__demo_static_texture_2", [150, 150], [200, 200], label="static 2") dpg.add_image_series("__demo_dynamic_texture_1", [-200, 100], [-100, 200], label="dynamic 1") dpg.fit_axis_data(dpg.top_container_stack()) dpg.fit_axis_data(xaxis) with dpg.tree_node(label="Candle Stick Series"): dates = [1546300800,1546387200,1546473600,1546560000,1546819200,1546905600,1546992000,1547078400,1547164800,1547424000,1547510400,1547596800,1547683200,1547769600,1547942400,1548028800,1548115200,1548201600,1548288000,1548374400,1548633600,1548720000,1548806400,1548892800,1548979200,1549238400,1549324800,1549411200,1549497600,1549584000,1549843200,1549929600,1550016000,1550102400,1550188800,1550361600,1550448000,1550534400,1550620800,1550707200,1550793600,1551052800,1551139200,1551225600,1551312000,1551398400,1551657600,1551744000,1551830400,1551916800,1552003200,1552262400,1552348800,1552435200,1552521600,1552608000,1552867200,1552953600,1553040000,1553126400,1553212800,1553472000,1553558400,1553644800,1553731200,1553817600,1554076800,1554163200,1554249600,1554336000,1554422400,1554681600,1554768000,1554854400,1554940800,1555027200,1555286400,1555372800,1555459200,1555545600,1555632000,1555891200,1555977600,1556064000,1556150400,1556236800,1556496000,1556582400,1556668800,1556755200,1556841600,1557100800,1557187200,1557273600,1557360000,1557446400,1557705600,1557792000,1557878400,1557964800,1558051200,1558310400,1558396800,1558483200,1558569600,1558656000,1558828800,1558915200,1559001600,1559088000,1559174400,1559260800,1559520000,1559606400,1559692800,1559779200,1559865600,1560124800,1560211200,1560297600,1560384000,1560470400,1560729600,1560816000,1560902400,1560988800,1561075200,1561334400,1561420800,1561507200,1561593600,1561680000,1561939200,1562025600,1562112000,1562198400,1562284800,1562544000,1562630400,1562716800,1562803200,1562889600,1563148800,1563235200,1563321600,1563408000,1563494400,1563753600,1563840000,1563926400,1564012800,1564099200,1564358400,1564444800,1564531200,1564617600,1564704000,1564963200,1565049600,1565136000,1565222400,1565308800,1565568000,1565654400,1565740800,1565827200,1565913600,1566172800,1566259200,1566345600,1566432000,1566518400,1566777600,1566864000,1566950400,1567036800,1567123200,1567296000,1567382400,1567468800,1567555200,1567641600,1567728000,1567987200,1568073600,1568160000,1568246400,1568332800,1568592000,1568678400,1568764800,1568851200,1568937600,1569196800,1569283200,1569369600,1569456000,1569542400,1569801600,1569888000,1569974400,1570060800,1570147200,1570406400,1570492800,1570579200,1570665600,1570752000,1571011200,1571097600,1571184000,1571270400,1571356800,1571616000,1571702400,1571788800,1571875200,1571961600] opens = [1284.7,1319.9,1318.7,1328,1317.6,1321.6,1314.3,1325,1319.3,1323.1,1324.7,1321.3,1323.5,1322,1281.3,1281.95,1311.1,1315,1314,1313.1,1331.9,1334.2,1341.3,1350.6,1349.8,1346.4,1343.4,1344.9,1335.6,1337.9,1342.5,1337,1338.6,1337,1340.4,1324.65,1324.35,1349.5,1371.3,1367.9,1351.3,1357.8,1356.1,1356,1347.6,1339.1,1320.6,1311.8,1314,1312.4,1312.3,1323.5,1319.1,1327.2,1332.1,1320.3,1323.1,1328,1330.9,1338,1333,1335.3,1345.2,1341.1,1332.5,1314,1314.4,1310.7,1314,1313.1,1315,1313.7,1320,1326.5,1329.2,1314.2,1312.3,1309.5,1297.4,1293.7,1277.9,1295.8,1295.2,1290.3,1294.2,1298,1306.4,1299.8,1302.3,1297,1289.6,1302,1300.7,1303.5,1300.5,1303.2,1306,1318.7,1315,1314.5,1304.1,1294.7,1293.7,1291.2,1290.2,1300.4,1284.2,1284.25,1301.8,1295.9,1296.2,1304.4,1323.1,1340.9,1341,1348,1351.4,1351.4,1343.5,1342.3,1349,1357.6,1357.1,1354.7,1361.4,1375.2,1403.5,1414.7,1433.2,1438,1423.6,1424.4,1418,1399.5,1435.5,1421.25,1434.1,1412.4,1409.8,1412.2,1433.4,1418.4,1429,1428.8,1420.6,1441,1460.4,1441.7,1438.4,1431,1439.3,1427.4,1431.9,1439.5,1443.7,1425.6,1457.5,1451.2,1481.1,1486.7,1512.1,1515.9,1509.2,1522.3,1513,1526.6,1533.9,1523,1506.3,1518.4,1512.4,1508.8,1545.4,1537.3,1551.8,1549.4,1536.9,1535.25,1537.95,1535.2,1556,1561.4,1525.6,1516.4,1507,1493.9,1504.9,1506.5,1513.1,1506.5,1509.7,1502,1506.8,1521.5,1529.8,1539.8,1510.9,1511.8,1501.7,1478,1485.4,1505.6,1511.6,1518.6,1498.7,1510.9,1510.8,1498.3,1492,1497.7,1484.8,1494.2,1495.6,1495.6,1487.5,1491.1,1495.1,1506.4] highs = [1284.75,1320.6,1327,1330.8,1326.8,1321.6,1326,1328,1325.8,1327.1,1326,1326,1323.5,1322.1,1282.7,1282.95,1315.8,1316.3,1314,1333.2,1334.7,1341.7,1353.2,1354.6,1352.2,1346.4,1345.7,1344.9,1340.7,1344.2,1342.7,1342.1,1345.2,1342,1350,1324.95,1330.75,1369.6,1374.3,1368.4,1359.8,1359,1357,1356,1353.4,1340.6,1322.3,1314.1,1316.1,1312.9,1325.7,1323.5,1326.3,1336,1332.1,1330.1,1330.4,1334.7,1341.1,1344.2,1338.8,1348.4,1345.6,1342.8,1334.7,1322.3,1319.3,1314.7,1316.6,1316.4,1315,1325.4,1328.3,1332.2,1329.2,1316.9,1312.3,1309.5,1299.6,1296.9,1277.9,1299.5,1296.2,1298.4,1302.5,1308.7,1306.4,1305.9,1307,1297.2,1301.7,1305,1305.3,1310.2,1307,1308,1319.8,1321.7,1318.7,1316.2,1305.9,1295.8,1293.8,1293.7,1304.2,1302,1285.15,1286.85,1304,1302,1305.2,1323,1344.1,1345.2,1360.1,1355.3,1363.8,1353,1344.7,1353.6,1358,1373.6,1358.2,1369.6,1377.6,1408.9,1425.5,1435.9,1453.7,1438,1426,1439.1,1418,1435,1452.6,1426.65,1437.5,1421.5,1414.1,1433.3,1441.3,1431.4,1433.9,1432.4,1440.8,1462.3,1467,1443.5,1444,1442.9,1447,1437.6,1440.8,1445.7,1447.8,1458.2,1461.9,1481.8,1486.8,1522.7,1521.3,1521.1,1531.5,1546.1,1534.9,1537.7,1538.6,1523.6,1518.8,1518.4,1514.6,1540.3,1565,1554.5,1556.6,1559.8,1541.9,1542.9,1540.05,1558.9,1566.2,1561.9,1536.2,1523.8,1509.1,1506.2,1532.2,1516.6,1519.7,1515,1519.5,1512.1,1524.5,1534.4,1543.3,1543.3,1542.8,1519.5,1507.2,1493.5,1511.4,1525.8,1522.2,1518.8,1515.3,1518,1522.3,1508,1501.5,1503,1495.5,1501.1,1497.9,1498.7,1492.1,1499.4,1506.9,1520.9] lows = [1282.85,1315,1318.7,1309.6,1317.6,1312.9,1312.4,1319.1,1319,1321,1318.1,1321.3,1319.9,1312,1280.5,1276.15,1308,1309.9,1308.5,1312.3,1329.3,1333.1,1340.2,1347,1345.9,1338,1340.8,1335,1332,1337.9,1333,1336.8,1333.2,1329.9,1340.4,1323.85,1324.05,1349,1366.3,1351.2,1349.1,1352.4,1350.7,1344.3,1338.9,1316.3,1308.4,1306.9,1309.6,1306.7,1312.3,1315.4,1319,1327.2,1317.2,1320,1323,1328,1323,1327.8,1331.7,1335.3,1336.6,1331.8,1311.4,1310,1309.5,1308,1310.6,1302.8,1306.6,1313.7,1320,1322.8,1311,1312.1,1303.6,1293.9,1293.5,1291,1277.9,1294.1,1286,1289.1,1293.5,1296.9,1298,1299.6,1292.9,1285.1,1288.5,1296.3,1297.2,1298.4,1298.6,1302,1300.3,1312,1310.8,1301.9,1292,1291.1,1286.3,1289.2,1289.9,1297.4,1283.65,1283.25,1292.9,1295.9,1290.8,1304.2,1322.7,1336.1,1341,1343.5,1345.8,1340.3,1335.1,1341.5,1347.6,1352.8,1348.2,1353.7,1356.5,1373.3,1398,1414.7,1427,1416.4,1412.7,1420.1,1396.4,1398.8,1426.6,1412.85,1400.7,1406,1399.8,1404.4,1415.5,1417.2,1421.9,1415,1413.7,1428.1,1434,1435.7,1427.5,1429.4,1423.9,1425.6,1427.5,1434.8,1422.3,1412.1,1442.5,1448.8,1468.2,1484.3,1501.6,1506.2,1498.6,1488.9,1504.5,1518.3,1513.9,1503.3,1503,1506.5,1502.1,1503,1534.8,1535.3,1541.4,1528.6,1525.6,1535.25,1528.15,1528,1542.6,1514.3,1510.7,1505.5,1492.1,1492.9,1496.8,1493.1,1503.4,1500.9,1490.7,1496.3,1505.3,1505.3,1517.9,1507.4,1507.1,1493.3,1470.5,1465,1480.5,1501.7,1501.4,1493.3,1492.1,1505.1,1495.7,1478,1487.1,1480.8,1480.6,1487,1488.3,1484.8,1484,1490.7,1490.4,1503.1] closes = [1283.35,1315.3,1326.1,1317.4,1321.5,1317.4,1323.5,1319.2,1321.3,1323.3,1319.7,1325.1,1323.6,1313.8,1282.05,1279.05,1314.2,1315.2,1310.8,1329.1,1334.5,1340.2,1340.5,1350,1347.1,1344.3,1344.6,1339.7,1339.4,1343.7,1337,1338.9,1340.1,1338.7,1346.8,1324.25,1329.55,1369.6,1372.5,1352.4,1357.6,1354.2,1353.4,1346,1341,1323.8,1311.9,1309.1,1312.2,1310.7,1324.3,1315.7,1322.4,1333.8,1319.4,1327.1,1325.8,1330.9,1325.8,1331.6,1336.5,1346.7,1339.2,1334.7,1313.3,1316.5,1312.4,1313.4,1313.3,1312.2,1313.7,1319.9,1326.3,1331.9,1311.3,1313.4,1309.4,1295.2,1294.7,1294.1,1277.9,1295.8,1291.2,1297.4,1297.7,1306.8,1299.4,1303.6,1302.2,1289.9,1299.2,1301.8,1303.6,1299.5,1303.2,1305.3,1319.5,1313.6,1315.1,1303.5,1293,1294.6,1290.4,1291.4,1302.7,1301,1284.15,1284.95,1294.3,1297.9,1304.1,1322.6,1339.3,1340.1,1344.9,1354,1357.4,1340.7,1342.7,1348.2,1355.1,1355.9,1354.2,1362.1,1360.1,1408.3,1411.2,1429.5,1430.1,1426.8,1423.4,1425.1,1400.8,1419.8,1432.9,1423.55,1412.1,1412.2,1412.8,1424.9,1419.3,1424.8,1426.1,1423.6,1435.9,1440.8,1439.4,1439.7,1434.5,1436.5,1427.5,1432.2,1433.3,1441.8,1437.8,1432.4,1457.5,1476.5,1484.2,1519.6,1509.5,1508.5,1517.2,1514.1,1527.8,1531.2,1523.6,1511.6,1515.7,1515.7,1508.5,1537.6,1537.2,1551.8,1549.1,1536.9,1529.4,1538.05,1535.15,1555.9,1560.4,1525.5,1515.5,1511.1,1499.2,1503.2,1507.4,1499.5,1511.5,1513.4,1515.8,1506.2,1515.1,1531.5,1540.2,1512.3,1515.2,1506.4,1472.9,1489,1507.9,1513.8,1512.9,1504.4,1503.9,1512.8,1500.9,1488.7,1497.6,1483.5,1494,1498.3,1494.1,1488.1,1487.5,1495.7,1504.7,1505.3] with dpg.plot(label="Candle Series", height=400, width=-1): dpg.add_plot_legend() xaxis = dpg.add_plot_axis(dpg.mvXAxis, label="Day", scale=dpg.mvPlotScale_Time) with dpg.plot_axis(dpg.mvYAxis, label="USD"): dpg.add_candle_series(dates, opens, closes, lows, highs, label="GOOGL", time_unit=dpg.mvTimeUnit_Day) dpg.fit_axis_data(dpg.top_container_stack()) dpg.fit_axis_data(xaxis) with dpg.tab(label="Subplots"): with dpg.tree_node(label="Basic"): with dpg.subplots(3, 3, label="My Subplots", width=-1, height=-1, row_ratios=[5.0, 1.0, 1.0], column_ratios=[5.0, 1.0, 1.0]) as subplot_id: for i in range(9): with dpg.plot(no_title=True): dpg.add_plot_axis(dpg.mvXAxis, label="", no_tick_labels=True) with dpg.plot_axis(dpg.mvYAxis, label="", no_tick_labels=True): dpg.add_line_series(sindatax, sindatay, label="0.5 + 0.5 * sin(x)") _add_config_options(subplot_id, 1, "no_resize", "no_title", before=subplot_id) with dpg.tree_node(label="Item Sharing"): with dpg.subplots(2, 3, label="", width=-1, height=-1) as subplot_id: dpg.add_plot_legend() for i in range(6): with dpg.plot(no_title=True): dpg.add_plot_axis(dpg.mvXAxis, label="") with dpg.plot_axis(dpg.mvYAxis, label=""): dpg.add_line_series(sindatax, sindatay, label="data" + str(i)) _add_config_options(subplot_id, 1, "column_major", before=subplot_id) with dpg.tree_node(label="Linked Axes"): with dpg.subplots(2, 2, label="", width=-1, height=-1) as subplot_id: dpg.add_plot_legend() for i in range(4): with dpg.plot(no_title=True): dpg.add_plot_axis(dpg.mvXAxis, label="") with dpg.plot_axis(dpg.mvYAxis, label=""): dpg.add_line_series(sindatax, sindatay, label="data" + str(i)) _add_config_options(subplot_id, 2, "no_align", "link_rows", "link_columns", "link_all_x", "link_all_y", before=subplot_id) with dpg.tab(label="Axes"): with dpg.tree_node(label="Time Axes"): timedatax = [] timedatay = [] time_index = 0 while time_index < 739497600: timedatax.append(time_index) timedatay.append(time_index/(60*60*24)) time_index+=60*60*24*7 dpg.add_text("When time is enabled, x-axis values are interpreted as UNIX timestamps in seconds (e.g. 1599243545).", bullet=True) dpg.add_text("UNIX timestamps are seconds since 00:00:00 UTC on 1 January 1970", bullet=True) with dpg.plot(label="Time Plot", height=400, width=-1): xaxis = dpg.add_plot_axis(dpg.mvXAxis, label="Date", scale=dpg.mvPlotScale_Time) with dpg.plot_axis(dpg.mvYAxis, label="Days since 1970"): dpg.add_line_series(timedatax, timedatay, label="Days") dpg.fit_axis_data(dpg.top_container_stack()) dpg.fit_axis_data(xaxis) with dpg.tree_node(label="Multi Axes Plot"): def show_hide_axis(axis, value): dpg.configure_item(axis, show=value) dpg.add_checkbox(label="Show Y1", tag="show_y1", default_value=True, callback=lambda:show_hide_axis("y1_axis", dpg.get_value("show_y1"))) dpg.add_checkbox(label="Show Y2", tag="show_y2", default_value=True, callback=lambda:show_hide_axis("y2_axis", dpg.get_value("show_y2"))) dpg.add_checkbox(label="Show Y3", tag="show_y3", default_value=True, callback=lambda:show_hide_axis("y3_axis", dpg.get_value("show_y3"))) dpg.add_checkbox(label="Show X1", tag="show_x1", default_value=True, callback=lambda:show_hide_axis("x1_axis", dpg.get_value("show_x1"))) dpg.add_checkbox(label="Show X2", tag="show_x2", default_value=True, callback=lambda:show_hide_axis("x2_axis", dpg.get_value("show_x2"))) dpg.add_checkbox(label="Show X3", tag="show_x3", default_value=True, callback=lambda:show_hide_axis("x3_axis", dpg.get_value("show_x3"))) #TODO Dragging a label from left to right is a bit sketchy with dpg.plot(label="Multi Axes Plot", height=400, width=-1): dpg.add_plot_legend() # create x axis dpg.add_plot_axis(dpg.mvXAxis, label="x1", tag="x1_axis") # create y axis 1 with dpg.plot_axis(dpg.mvYAxis, label="y1", tag="y1_axis"): dpg.add_line_series(sindatax, sindatay, label="y1") dpg.add_plot_axis(dpg.mvXAxis2, label="x2", tag="x2_axis", opposite=True) # create y axis 2 with dpg.plot_axis(dpg.mvYAxis2, label="y2", tag="y2_axis", opposite=True): dpg.add_line_series(sindatax, cosdatay, label="y2") dpg.add_plot_axis(dpg.mvXAxis3, label="x3", tag="x3_axis") # create y axis 3 with dpg.plot_axis(dpg.mvYAxis3, label="y3", tag="y3_axis"): dpg.add_line_series(sindatax, sindatay, label="0.5 + 0.5 * sin(x)") with dpg.tree_node(label="Ordering Axes Plot"): dpg.add_checkbox(label="Opposite X", default_value=False, callback=lambda _, val: dpg.configure_item("x_axis_ordering", opposite=val)) dpg.add_checkbox(label="Invert X", default_value=False, callback=lambda _, val: dpg.configure_item("x_axis_ordering", invert=val)) dpg.add_checkbox(label="Opposite Y", default_value=False, callback=lambda _, val: dpg.configure_item("y_axis_ordering", opposite=val)) dpg.add_checkbox(label="Invert Y", default_value=False, callback=lambda _, val: dpg.configure_item("y_axis_ordering", invert=val)) with dpg.plot(label="Ordering Axes Plot", height=400, width=-1): dpg.add_plot_legend() # create x axis dpg.add_plot_axis(dpg.mvXAxis, label="x", tag="x_axis_ordering") # create y axis 1 with dpg.plot_axis(dpg.mvYAxis, label="y", tag="y_axis_ordering"): dpg.add_line_series(sindatax, sindatay) with dpg.tree_node(label="Log Axis Scale"): xs = [0.0 for i in range(1001)] ys1 = [0.0 for i in range(1001)] ys2 = [0.0 for i in range(1001)] ys3 = [0.0 for i in range(1001)] for i in range(1,1001): xs[i] = i*0.1 ys1[i] = sin(xs[i]) + 1 ys2[i] = log10(xs[i]) ys3[i] = pow(10.0, xs[i]) with dpg.plot(label="Log Axes Plot", height=400, width=-1): dpg.add_plot_legend() # create x axis xaxis = dpg.add_plot_axis(dpg.mvXAxis, label="x1", scale=dpg.mvPlotScale_Log10) dpg.set_axis_limits(xaxis, 0.1, 100) # create y axis 1 with dpg.plot_axis(dpg.mvYAxis) as yaxis: dpg.add_line_series(xs, xs, label="x") dpg.add_line_series(xs, ys1, label="sin(x)+1") dpg.add_line_series(xs, ys2, label="log(x)") dpg.add_line_series(xs, ys3, label="10^x") dpg.set_axis_limits(yaxis, 0, 10) with dpg.tree_node(label="Time Axis"): t_min = 1609459200; # 01/01/2021 @ 12:00:00am (UTC) t_max = 1640995200; # 01/01/2022 @ 12:00:00am (UTC) t_temp = t_min while t_temp < t_max: xs.append(t_temp) ys1.append(sin(t_temp)) ys2.append(cos(t_temp)) t_temp += 86400 with dpg.plot(label="Time Plot", height=400, width=-1): dpg.add_plot_legend() # create x axis xaxis = dpg.add_plot_axis(dpg.mvXAxis, label="x1", scale=dpg.mvPlotScale_Time) dpg.set_axis_limits(xaxis, t_min, t_max) # create y axis 1 with dpg.plot_axis(dpg.mvYAxis) as yaxis: dpg.add_line_series(xs, ys1, label="sin(x)+1") dpg.add_line_series(xs, ys2, label="log(x)") with dpg.tree_node(label="Symmetric Log Axis Scale"): xs = [0.0 for i in range(1000)] ys1 = [0.0 for i in range(1000)] ys2 = [0.0 for i in range(1000)] for i in range(1000): xs[i] = i*0.1-50 ys1[i] = sin(xs[i]) ys2[i] = i*0.002 - 1 with dpg.plot(label="Symmetric Log Axes Plot", height=400, width=-1): dpg.add_plot_legend() # create x axis dpg.add_plot_axis(dpg.mvXAxis, label="x1", scale=dpg.mvPlotScale_SymLog) # create y axis 1 with dpg.plot_axis(dpg.mvYAxis): dpg.add_line_series(xs, ys1, label="y1") dpg.add_line_series(xs, ys2, label="y2") with dpg.tab(label="Tools"): with dpg.tree_node(label="Querying"): dpg.add_text("Right click to box select and then click using the cancel button (standard to Left click)") dpg.add_text("Double left click to delete the last drag rect drawn.") dpg.add_slider_int(min_value=0, max_value=100, default_value=1, label="Min query rects", callback=lambda _, val: dpg.configure_item("query_plot_1", min_query_rects=val)) dpg.add_slider_int(min_value=0, max_value=100, default_value=1, label="Max query rects", callback=lambda _, val: dpg.configure_item("query_plot_1", max_query_rects=val)) def query(sender, app_data, user_data): if not len(app_data): return dpg.set_axis_limits(user_data[0], app_data[0][0], app_data[0][2]) dpg.set_axis_limits(user_data[1], app_data[0][3], app_data[0][1]) # plot 1 with dpg.plot(no_title=True, height=400, tag="query_plot_1", callback=query, query=True, no_menus=True, width=-1) as plot_id: dpg.add_plot_axis(dpg.mvXAxis, label="x") with dpg.plot_axis(dpg.mvYAxis, label="y"): dpg.add_line_series(sindatax, sindatay) dpg.add_text("This plot takes care only of the first query rect") # plot 2 with dpg.plot(no_title=True, height=400, no_menus=True, width=-1, tag="plot2"): xaxis_id2 = dpg.add_plot_axis(dpg.mvXAxis, label="x") yaxis_id2 = dpg.add_plot_axis(dpg.mvYAxis, label="y") dpg.add_line_series(sindatax, sindatay, parent=yaxis_id2) # set plot 1 user data to axis so the query callback has access dpg.configure_item(plot_id, user_data=(xaxis_id2,yaxis_id2)) with dpg.tree_node(label="Drag Lines/Points"): with dpg.plot(label="Drag Lines/Points", height=400, width=-1): dpg.add_plot_legend() dpg.add_plot_axis(dpg.mvXAxis, label="x") dpg.add_plot_axis(dpg.mvYAxis, label="y") # drag lines/points belong to the plot NOT axis dpg.add_drag_line(label="dline1", color=[255, 0, 0, 255]) dpg.add_drag_line(color=[255, 255, 0, 255], vertical=False) dpg.add_drag_point(label="dpoint1", color=[255, 0, 255, 255]) dpg.add_drag_point(label="dpoint2", color=[255, 0, 255, 255]) with dpg.tree_node(label="Drag Rects"): def drag_query(sender, app_data, user_data): dpg.set_axis_limits(user_data[0], app_data[0][0], app_data[0][2]) dpg.set_axis_limits(user_data[1], app_data[0][3], app_data[0][1]) with dpg.plot(label="Drag Rects", height=400, width=-1, callback=drag_query) as plot_drag: dpg.add_plot_axis(dpg.mvXAxis, label="x") with dpg.plot_axis(dpg.mvYAxis, label="y"): dpg.add_line_series(sindatax, sindatay) # drag rects belong to the plot NOT axis dpg.add_drag_rect(label="drag rect 1", tag="drag_rect", color=[255, 0, 0, 255], default_value=(-1,1)) with dpg.plot(no_title=True, height=400, no_menus=True, width=-1, tag="drag_plot2"): xaxis_drag2 = dpg.add_plot_axis(dpg.mvXAxis, label="x") yaxis_drag2 = dpg.add_plot_axis(dpg.mvYAxis, label="y") dpg.add_line_series(sindatax, sindatay, parent=yaxis_drag2) # set plot 1 user data to axis so the query callback has access dpg.configure_item(plot_drag, user_data=(xaxis_drag2,yaxis_drag2)) with dpg.tree_node(label="Annotations"): with dpg.plot(label="Annotations", height=400, width=-1): dpg.add_plot_legend() dpg.add_plot_axis(dpg.mvXAxis, label="x") dpg.add_plot_axis(dpg.mvYAxis, label="y") dpg.add_line_series(sindatax, sindatay, label="0.5 + 0.5 * sin(x)", parent=dpg.last_item()) # annotations belong to the plot NOT axis dpg.add_plot_annotation(label="BL", default_value=(0.25, 0.25), offset=(-15, 15), color=[255, 255, 0, 255]) dpg.add_plot_annotation(label="BR", default_value=(0.75, 0.25), offset=(15, 15), color=[255, 255, 0, 255]) dpg.add_plot_annotation(label="TR not clampled", default_value=(0.75, 0.75), offset=(-15, -15), color=[255, 255, 0, 255], clamped=False) dpg.add_plot_annotation(label="TL", default_value=(0.25, 0.75), offset=(-15, -15), color=[255, 255, 0, 255]) dpg.add_plot_annotation(label="Center", default_value=(0.5, 0.5), color=[255, 255, 0, 255]) with dpg.tree_node(label="Tags"): with dpg.plot(height=400, width=-1): with dpg.plot_axis(dpg.mvXAxis): dpg.add_axis_tag(default_value=0.25, color=(255, 255, 0, 255)) with dpg.plot_axis(dpg.mvYAxis): dpg.add_axis_tag(default_value=0.75, color=(255, 255, 0, 255)) dpg.add_drag_line(vertical=False, label="Drag", default_value=0.25, color=(255, 0, 0, 255), no_fit=True) with dpg.plot_axis(dpg.mvXAxis2): dpg.add_axis_tag(default_value=0.5, color=(0, 255, 255, 255), label="MyTag") with dpg.plot_axis(dpg.mvYAxis2): dpg.add_axis_tag(default_value=0.5, color=(0, 255, 255, 255), label="Tag: 42") with dpg.tree_node(label="Drag & Drop"): sindatax = [] sindatay = [] for i in range(100): sindatax.append(i/100) sindatay.append(0.5 + 0.5*sin(50*i/100)) with dpg.group(horizontal=True): with dpg.group(): dpg.add_text("Sources:") dpg.add_button(label="Source 1") with dpg.drag_payload(parent=dpg.last_item(), drag_data=(sindatax, sindatay, "Source 1"), payload_type="plotting"): dpg.add_text("Source 1") dpg.add_simple_plot(label="", default_value=sindatay) def _legend_drop(sender, app_data, user_data): parent = dpg.get_item_info(sender)["parent"] yaxis2 = dpg.get_item_info(parent)["children"][1][2] dpg.add_line_series(app_data[0], app_data[1], label=app_data[2], parent=yaxis2) dpg.add_button(label="Delete Series", user_data = dpg.last_item(), parent=dpg.last_item(), callback=lambda s, a, u: dpg.delete_item(u)) def _plot_drop(sender, app_data, user_data): yaxis1 = dpg.get_item_info(sender)["children"][1][0] dpg.add_line_series(app_data[0], app_data[1], label=app_data[2], parent=yaxis1) dpg.add_button(label="Delete Series", user_data = dpg.last_item(), parent=dpg.last_item(), callback=lambda s, a, u: dpg.delete_item(u)) def _axis_drop(sender, app_data, user_data): dpg.add_line_series(app_data[0], app_data[1], label=app_data[2], parent=sender) dpg.add_button(label="Delete Series", user_data = dpg.last_item(), parent=dpg.last_item(), callback=lambda s, a, u: dpg.delete_item(u)) with dpg.plot(label="Drag/Drop Plot", height=400, width=-1, drop_callback=_plot_drop, payload_type="plotting"): dpg.add_plot_legend(drop_callback=_legend_drop, payload_type="plotting") dpg.add_plot_axis(dpg.mvXAxis, label="x") # create y axes with drop callbacks dpg.add_plot_axis(dpg.mvYAxis, label="y1", drop_callback=_axis_drop, payload_type="plotting") dpg.add_plot_axis(dpg.mvYAxis2, label="y2", drop_callback=_axis_drop, payload_type="plotting") dpg.add_plot_axis(dpg.mvYAxis3, label="y3", drop_callback=_axis_drop, payload_type="plotting") with dpg.tree_node(label="Legend Options"): def add_remove_location(type, add): if add: dpg.configure_item("plot_legend", location = dpg.get_item_configuration("plot_legend")['location'] + type) else: dpg.configure_item("plot_legend", location = dpg.get_item_configuration("plot_legend")['location'] - type) with dpg.group(horizontal=True): dpg.add_checkbox(label="North", tag="north_legend", callback=lambda: add_remove_location(dpg.mvPlot_Location_North, dpg.get_value("north_legend"))) dpg.add_checkbox(label="East", tag="east_legend", callback=lambda: add_remove_location(dpg.mvPlot_Location_East, dpg.get_value("east_legend"))) dpg.add_checkbox(label="West", tag="west_legend", callback=lambda: add_remove_location(dpg.mvPlot_Location_West, dpg.get_value("west_legend"))) dpg.add_checkbox(label="South", tag="south_legend", callback=lambda: add_remove_location(dpg.mvPlot_Location_South, dpg.get_value("south_legend"))) dpg.add_checkbox(label="Horizontal", tag="horizontal_legend", callback=lambda: dpg.configure_item("plot_legend", horizontal=dpg.get_value("horizontal_legend"))) dpg.add_checkbox(label="Outside", tag="outside_legend", callback=lambda: dpg.configure_item("plot_legend", outside=dpg.get_value("outside_legend"))) dpg.add_checkbox(label="Sort", tag="sort_legend", callback=lambda: dpg.configure_item("plot_legend", sort=dpg.get_value("sort_legend"))) with dpg.plot(): dpg.add_plot_legend(tag="plot_legend", location=0, outside=False, sort=False, horizontal=False) with dpg.plot_axis(dpg.mvYAxis): dpg.add_line_series(sindatax, sindatay, label="2") dpg.add_line_series(sindatax, sindatay, label="1") dpg.add_line_series(sindatax, sindatay, label="3") with dpg.tree_node(label="Legend Popups"): vals=[] frequency = 0.1 amplitude = 0.5 color = (1,1,0,1) alpha = 1.0 line = False thickness = 1 markers = False shaded = False x = [i for i in range(101)] vals = [0.0 for i in range(101)] for i in range(101): vals[i] = amplitude * sin(frequency * i) def recalculate_vals(amplitude, frequency): for i in range(101): vals[i] = amplitude * sin(frequency * i) dpg.configure_item("bar_custom_legend", y=vals) with dpg.plot(label="Line Series"): dpg.add_plot_legend() dpg.add_plot_axis(dpg.mvXAxis, label="x") with dpg.plot_axis(dpg.mvYAxis): dpg.add_bar_series(x, vals, tag="bar_custom_legend", label="Right Click Me!") with dpg.group(parent=dpg.last_item()): dpg.add_slider_float(label="Frequency", default_value=frequency, min_value=0.01, max_value=5.0, tag="frequency", callback=lambda: recalculate_vals(dpg.get_value("amplitude"), dpg.get_value("frequency"))) dpg.add_slider_float(label="Amplitude", default_value=amplitude, min_value=0.01, max_value=5.0, tag="amplitude", callback=lambda: recalculate_vals(dpg.get_value("amplitude"), dpg.get_value("frequency"))) dpg.add_separator() with dpg.tab(label="Custom"): with dpg.tree_node(label="Custom Context Menus"): dpg.add_text("Right-click the series in the legend.", bullet=True) dpg.add_text("Series are containers. Children will show up in the custom context menu.", bullet=True) # create plot with dpg.plot(label="Line Series", height=400, width=-1): dpg.add_plot_legend() dpg.add_plot_axis(dpg.mvXAxis, label="x") with dpg.plot_axis(dpg.mvYAxis, label="y"): # series 1 dpg.add_line_series(sindatax, sindatay, label="series 1") dpg.add_button(label="Delete Series 1", user_data = dpg.last_item(), parent=dpg.last_item(), callback=lambda s, a, u: dpg.delete_item(u)) # series 2 dpg.add_line_series(sindatax, sindatay, label="series 2") dpg.add_button(label="Delete Series 2", user_data = dpg.last_item(), parent=dpg.last_item(), callback=lambda s, a, u: dpg.delete_item(u)) with dpg.tree_node(label="Custom Rendering"): # create plot with dpg.plot(label="Custom Rendering", height=400, width=-1): dpg.add_plot_axis(dpg.mvXAxis, label="x") dpg.add_plot_axis(dpg.mvYAxis, label="y") dpg.draw_line((0, 0), (1, 2), color=(255, 0, 0, 255), thickness=0.01) dpg.draw_text((0, 0), "Origin", color=(250, 250, 250, 255), size=0.1) with dpg.tree_node(label="Custom Series"): def _custom_series_callback(sender, app_data): _helper_data = app_data[0] transformed_x = app_data[1] transformed_y = app_data[2] mouse_x_plot_space = _helper_data["MouseX_PlotSpace"] mouse_y_plot_space = _helper_data["MouseY_PlotSpace"] mouse_x_pixel_space = _helper_data["MouseX_PixelSpace"] mouse_y_pixel_space = _helper_data["MouseY_PixelSpace"] dpg.delete_item(sender, children_only=True, slot=2) dpg.push_container_stack(sender) dpg.configure_item("demo_custom_series", tooltip=False) for i in range(0, len(transformed_x)): dpg.draw_text((transformed_x[i]+15, transformed_y[i]-15), str(i), size=20) dpg.draw_circle((transformed_x[i], transformed_y[i]), 15, fill=(50+i*5, 50+i*50, 0, 255)) if mouse_x_pixel_space < transformed_x[i]+15 and mouse_x_pixel_space > transformed_x[i]-15 and mouse_y_pixel_space > transformed_y[i]-15 and mouse_y_pixel_space < transformed_y[i]+15: dpg.draw_circle((transformed_x[i], transformed_y[i]), 30) dpg.configure_item("demo_custom_series", tooltip=True) dpg.set_value("demo_custom_series_text", "Current Point: " + str(i)) dpg.pop_container_stack() # create plot dpg.add_text("Hover an item for a custom tooltip!") with dpg.plot(label="Custom Series", height=400, width=-1): dpg.add_plot_legend() xaxis = dpg.add_plot_axis(dpg.mvXAxis) with dpg.plot_axis(dpg.mvYAxis): with dpg.custom_series([0.0, 1.0, 2.0, 4.0, 5.0], [0.0, 10.0, 20.0, 40.0, 50.0], 2, label="Custom Series", callback=_custom_series_callback, tag="demo_custom_series"): dpg.add_text("Current Point: ", tag="demo_custom_series_text") dpg.fit_axis_data(dpg.top_container_stack()) with dpg.tab(label="Help"): dpg.add_text("Plotting User Guide") dpg.add_text("Left click and drag within the plot area to pan X and Y axes.", bullet=True) dpg.add_text("Left click and drag on an axis to pan an individual axis.", bullet=True, indent=20) dpg.add_text("Scoll in the plot area to zoom both X and Y axes.", bullet=True) dpg.add_text("Scroll on an axis to zoom an individual axis.", bullet=True, indent=20) dpg.add_text("Right click and drag to box select data.", bullet=True) dpg.add_text("Hold Alt to expand box selection horizontally.", bullet=True, indent=20) dpg.add_text("Hold Shift to expand box selection vertically.", bullet=True, indent=20) dpg.add_text("Left click while box selecting to cancel the selection.", bullet=True, indent=20) dpg.add_text("Double left click to fit all visible data.", bullet=True) dpg.add_text("Double left click on an axis to fit the individual axis", bullet=True, indent=20) dpg.add_text("Double right click to open the plot context menu.", bullet=True) dpg.add_text("Click legend label icons to show/hide plot items.", bullet=True) dpg.add_text("IMPORTANT: By default, anti-aliased lines are turned OFF.", bullet=True) with dpg.collapsing_header(label="Node Editor"): dpg.add_text("Ctrl+Click to remove a link.", bullet=True) with dpg.node_editor(callback=lambda sender, app_data: dpg.add_node_link(app_data[0], app_data[1], parent=sender), delink_callback=lambda sender, app_data: dpg.delete_item(app_data), minimap=True, minimap_location=dpg.mvNodeMiniMap_Location_BottomRight): with dpg.node(label="Node 1", pos=[10, 10]): with dpg.node_attribute(): dpg.add_input_float(label="F1", width=150) with dpg.node_attribute(attribute_type=dpg.mvNode_Attr_Output): dpg.add_input_float(label="F2", width=150) with dpg.node(label="Node 2", pos=[300, 10]): with dpg.node_attribute() as na2: dpg.add_input_float(label="F3", width=200) with dpg.node_attribute(attribute_type=dpg.mvNode_Attr_Output): dpg.add_input_float(label="F4", width=200) with dpg.node(label="Node 3", pos=[25, 150]): with dpg.node_attribute(): dpg.add_input_text(label="T5", width=200) with dpg.node_attribute(attribute_type=dpg.mvNode_Attr_Static): dpg.add_simple_plot(label="Node Plot", default_value=(0.3, 0.9, 2.5, 8.9), width=200, height=80, histogram=True) with dpg.collapsing_header(label= "Filtering"): dpg.add_text("Filter usage:\n" " \"\" display all lines\n" " \"xxx\" display lines containing \"xxx\"\n" " \"xxx,yyy\" display lines containing \"xxx\" or \"yyy\"\n" " \"-xxx\" hide lines containing \"xxx\"") dpg.add_input_text(label="Filter (inc, -exc)", callback=lambda s, a: dpg.set_value("__demo_filter", a)) with dpg.filter_set(tag="__demo_filter"): dpg.add_text("aaa1.c", filter_key="aaa1.c", bullet=True) dpg.add_text("bbb1.c", filter_key="bbb1.c", bullet=True) dpg.add_text("ccc1.c", filter_key="ccc1.c", bullet=True) dpg.add_text("aaa2.cpp", filter_key="aaa2.cpp", bullet=True) dpg.add_text("bbb2.cpp", filter_key="bbb2.cpp", bullet=True) dpg.add_text("ccc2.cpp", filter_key="ccc2.cpp", bullet=True) dpg.add_text("abc.h", filter_key="abc.h", bullet=True) dpg.add_text("hello, world", filter_key="hello, world", bullet=True) with dpg.collapsing_header(label="Drawing API"): with dpg.tree_node(label="Basic"): draw_thickness = 3.0 draw_size = 36 draw_spacing = 10 draw_rounding = draw_size/5.0 draw_color = [255, 255, 0] with dpg.drawlist(width=300, height=200): draw_x = 4 draw_y = 4 for i in range(2): _draw_t = draw_thickness if i == 0: _draw_t = 1.0 dpg.draw_circle([draw_x + draw_size*0.5, draw_y + draw_size*0.5], draw_size*0.5, thickness=_draw_t, color=draw_color) draw_x = draw_x + draw_spacing + draw_size dpg.draw_rectangle([draw_x, draw_y], [draw_size + draw_x, draw_size + draw_y], thickness=_draw_t, color=draw_color) draw_x = draw_x + draw_spacing + draw_size dpg.draw_rectangle([draw_x, draw_y], [draw_size + draw_x, draw_size + draw_y], rounding=draw_rounding, thickness=_draw_t, color=draw_color) draw_x = draw_x + draw_spacing + draw_size dpg.draw_triangle([draw_x+draw_size*0.5,draw_y], [draw_x+draw_size, draw_y+draw_size-0.5], [draw_x, draw_y+draw_size-0.5], thickness=_draw_t, color=draw_color) draw_x = draw_x + draw_spacing + draw_size dpg.draw_line([draw_x, draw_y], [draw_x + draw_size, draw_y], thickness=_draw_t, color=draw_color) draw_x = draw_x + draw_spacing + draw_size dpg.draw_line([draw_x, draw_y], [draw_x, draw_y + draw_size], thickness=_draw_t, color=draw_color) draw_x = draw_x + draw_spacing + draw_size dpg.draw_line([draw_x, draw_y], [draw_x + draw_size, draw_y + draw_size], thickness=_draw_t, color=draw_color) draw_x = draw_x + draw_spacing + draw_size dpg.draw_bezier_quadratic([draw_x, draw_y + draw_size * 0.6], [draw_x + draw_size*0.5, draw_y - draw_size * 0.4], [draw_x + draw_size, draw_y + draw_size], thickness=_draw_t, color=draw_color) draw_x = draw_x + draw_spacing + draw_size dpg.draw_bezier_cubic([draw_x, draw_y], [draw_x + draw_size*1.3, draw_y + draw_size * 0.3], [draw_x+draw_size - draw_size*1.3, draw_y + draw_size - draw_size*0.3], [draw_x + draw_size, draw_y + draw_size], thickness=_draw_t, color=draw_color) draw_x = 4 draw_y = draw_y + draw_size + draw_spacing _draw_t = 0.0 dpg.draw_circle([draw_x + draw_size*0.5, draw_y + draw_size*0.5], draw_size*0.5, thickness=_draw_t, color=draw_color, fill=draw_color) draw_x = draw_x + draw_spacing + draw_size dpg.draw_rectangle([draw_size + draw_x, draw_size + draw_y], [draw_x, draw_y], thickness=_draw_t, color=draw_color, fill=draw_color) draw_x = draw_x + draw_spacing + draw_size dpg.draw_rectangle([draw_x, draw_y], [draw_size + draw_x, draw_size + draw_y], rounding=draw_rounding, thickness=_draw_t, color=draw_color, fill=draw_color) draw_x = draw_x + draw_spacing + draw_size dpg.draw_triangle([draw_x+draw_size*0.5,draw_y], [draw_x+draw_size, draw_y+draw_size-0.5], [draw_x, draw_y+draw_size-0.5], thickness=_draw_t, color=draw_color, fill=draw_color) draw_x = draw_x + draw_spacing + draw_size dpg.draw_rectangle([draw_size + draw_x, draw_size + draw_y], [draw_x, draw_y], color=[0, 0, 0, 0], thickness=_draw_t, corner_colors=[[0, 0, 0], [255, 0, 0], [0, 255, 0], [255, 255, 0]], multicolor=True) with dpg.tree_node(label="Draw Nodes & 3D transforms"): with dpg.group(horizontal=True): with dpg.drawlist(width=500, height=500, tag="_demo_advanced_drawing"): with dpg.draw_layer(): dpg.draw_circle([250, 250], 150, color=[0, 255, 0]) dpg.draw_circle([250, 250], 200, color=[0, 255, 255]) with dpg.draw_node(tag="_drawing_sun"): dpg.apply_transform(dpg.last_item(), dpg.create_translation_matrix([250, 250])) dpg.draw_circle([0, 0], 15, color=[255, 255, 0], fill=[255, 255, 0]) with dpg.draw_node(tag="_drawing_planet1", user_data=45.0): dpg.apply_transform(dpg.last_item(), dpg.create_rotation_matrix(math.pi*45.0/180.0 , [0, 0, -1])*dpg.create_translation_matrix([150, 0])) dpg.draw_circle([0, 0], 10, color=[0, 255, 0], fill=[0, 255, 0]) dpg.draw_circle([0, 0], 25, color=[255, 0, 255]) with dpg.draw_node(tag="_drawing_moon1", user_data=45.0): dpg.apply_transform(dpg.last_item(), dpg.create_rotation_matrix(math.pi*45.0/180.0 , [0, 0, -1])*dpg.create_translation_matrix([25, 0])) dpg.draw_circle([0, 0], 5, color=[255, 0, 255], fill=[255, 0, 255]) with dpg.draw_node(tag="_drawing_planet2", user_data=0.0): dpg.apply_transform(dpg.last_item(), dpg.create_rotation_matrix(math.pi*0.0/180.0 , [0, 0, -1])*dpg.create_translation_matrix([200, 0])) dpg.draw_circle([0, 0], 10, color=[0, 255, 255], fill=[0, 255, 255]) dpg.draw_circle([0, 0], 25, color=[255, 0, 255]) dpg.draw_circle([0, 0], 45, color=[255, 255, 255]) with dpg.draw_node(tag="_drawing_moon2", user_data=45.0): dpg.apply_transform(dpg.last_item(), dpg.create_rotation_matrix(math.pi*45.0/180.0 , [0, 0, -1])*dpg.create_translation_matrix([25, 0])) dpg.draw_circle([0, 0], 5, color=[255, 0, 255], fill=[255, 0, 255]) with dpg.draw_node(tag="_drawing_moon3", user_data=120.0): dpg.apply_transform(dpg.last_item(), dpg.create_rotation_matrix(math.pi*120.0/180.0 , [0, 0, -1])*dpg.create_translation_matrix([45, 0])) dpg.draw_circle([0, 0], 5, color=[255, 255, 255], fill=[255, 255, 255]) def _demo_live_drawing(): planet_rot1 = dpg.get_item_user_data("_drawing_planet1") + 1.0 planet_rot2 = dpg.get_item_user_data("_drawing_planet2") + 2.0 moon_rot1 = dpg.get_item_user_data("_drawing_moon1") + 3.0 moon_rot2 = dpg.get_item_user_data("_drawing_moon2") + 7.0 moon_rot3 = dpg.get_item_user_data("_drawing_moon3") + 10.0 dpg.apply_transform("_drawing_planet1", dpg.create_rotation_matrix(math.pi*planet_rot1/180.0 , [0, 0, -1])*dpg.create_translation_matrix([150, 0])) dpg.apply_transform("_drawing_planet2", dpg.create_rotation_matrix(math.pi*planet_rot2/180.0 , [0, 0, -1])*dpg.create_translation_matrix([200, 0])) dpg.apply_transform("_drawing_moon1", dpg.create_rotation_matrix(math.pi*moon_rot1/180.0 , [0, 0, -1])*dpg.create_translation_matrix([25, 0])) dpg.apply_transform("_drawing_moon2", dpg.create_rotation_matrix(math.pi*moon_rot2/180.0 , [0, 0, -1])*dpg.create_translation_matrix([25, 0])) dpg.apply_transform("_drawing_moon3", dpg.create_rotation_matrix(math.pi*moon_rot3/180.0 , [0, 0, 1])*dpg.create_translation_matrix([45, 0])) dpg.set_item_user_data("_drawing_planet1", planet_rot1) dpg.set_item_user_data("_drawing_planet2", planet_rot2) dpg.set_item_user_data("_drawing_moon1", moon_rot1) dpg.set_item_user_data("_drawing_moon2", moon_rot2) dpg.set_item_user_data("_drawing_moon3", moon_rot3) with dpg.item_handler_registry(tag="__demo_item_reg6"): dpg.add_item_visible_handler(callback=_demo_live_drawing) dpg.bind_item_handler_registry("_demo_advanced_drawing", dpg.last_container()) size = 5 demo_verticies = [ [-size, -size, -size], # 0 near side [ size, -size, -size], # 1 [-size, size, -size], # 2 [ size, size, -size], # 3 [-size, -size, size], # 4 far side [ size, -size, size], # 5 [-size, size, size], # 6 [ size, size, size], # 7 [-size, -size, -size], # 8 left side [-size, size, -size], # 9 [-size, -size, size], # 10 [-size, size, size], # 11 [ size, -size, -size], # 12 right side [ size, size, -size], # 13 [ size, -size, size], # 14 [ size, size, size], # 15 [-size, -size, -size], # 16 bottom side [ size, -size, -size], # 17 [-size, -size, size], # 18 [ size, -size, size], # 19 [-size, size, -size], # 20 top side [ size, size, -size], # 21 [-size, size, size], # 22 [ size, size, size], # 23 ] demo_colors = [ [255, 0, 0, 150], [255, 255, 0, 150], [255, 255, 255, 150], [255, 0, 255, 150], [ 0, 255, 0, 150], [ 0, 255, 255, 150], [ 0, 0, 255, 150], [ 0, 125, 0, 150], [128, 0, 0, 150], [128, 70, 0, 150], [128, 255, 255, 150], [128, 0, 128, 150] ] with dpg.drawlist(width=500, height=500, tag="_demo_advanced_drawing_3d"): with dpg.draw_layer(depth_clipping=False, cull_mode=dpg.mvCullMode_Back, perspective_divide=True): dpg.set_clip_space(dpg.last_item(), 0, 0, 500, 500, -1.0, 1.0) with dpg.draw_node(tag="_demo_3dNode1", user_data=[0, 0, 0]): dpg.draw_triangle(demo_verticies[1], demo_verticies[2], demo_verticies[0], color=[0,0,0.0], fill=demo_colors[0]) dpg.draw_triangle(demo_verticies[1], demo_verticies[3], demo_verticies[2], color=[0,0,0.0], fill=demo_colors[1]) dpg.draw_triangle(demo_verticies[7], demo_verticies[5], demo_verticies[4], color=[0,0,0.0], fill=demo_colors[2]) dpg.draw_triangle(demo_verticies[6], demo_verticies[7], demo_verticies[4], color=[0,0,0.0], fill=demo_colors[3]) dpg.draw_triangle(demo_verticies[9], demo_verticies[10], demo_verticies[8], color=[0,0,0.0], fill=demo_colors[4]) dpg.draw_triangle(demo_verticies[9], demo_verticies[11], demo_verticies[10], color=[0,0,0.0], fill=demo_colors[5]) dpg.draw_triangle(demo_verticies[15], demo_verticies[13], demo_verticies[12], color=[0,0,0.0], fill=demo_colors[6]) dpg.draw_triangle(demo_verticies[14], demo_verticies[15], demo_verticies[12], color=[0,0,0.0], fill=demo_colors[7]) dpg.draw_triangle(demo_verticies[18], demo_verticies[17], demo_verticies[16], color=[0,0,0.0], fill=demo_colors[8]) dpg.draw_triangle(demo_verticies[19], demo_verticies[17], demo_verticies[18], color=[0,0,0.0], fill=demo_colors[9]) dpg.draw_triangle(demo_verticies[21], demo_verticies[23], demo_verticies[20], color=[0,0,0.0], fill=demo_colors[10]) dpg.draw_triangle(demo_verticies[23], demo_verticies[22], demo_verticies[20], color=[0,0,0.0], fill=demo_colors[11]) with dpg.group(horizontal=True): with dpg.drawlist(width=500, height=500): with dpg.draw_layer(depth_clipping=False, cull_mode=dpg.mvCullMode_Front, perspective_divide=True): dpg.set_clip_space(dpg.last_item(), 0, 0, 500, 500, -1.0, 1.0) with dpg.draw_node(tag="_demo_3dNode2", user_data=[0, 0, 0]): dpg.draw_triangle(demo_verticies[1], demo_verticies[2], demo_verticies[0], color=[0,0,0.0], fill=demo_colors[0]) dpg.draw_triangle(demo_verticies[1], demo_verticies[3], demo_verticies[2], color=[0,0,0.0], fill=demo_colors[1]) dpg.draw_triangle(demo_verticies[7], demo_verticies[5], demo_verticies[4], color=[0,0,0.0], fill=demo_colors[2]) dpg.draw_triangle(demo_verticies[6], demo_verticies[7], demo_verticies[4], color=[0,0,0.0], fill=demo_colors[3]) dpg.draw_triangle(demo_verticies[9], demo_verticies[10], demo_verticies[8], color=[0,0,0.0], fill=demo_colors[4]) dpg.draw_triangle(demo_verticies[9], demo_verticies[11], demo_verticies[10], color=[0,0,0.0], fill=demo_colors[5]) dpg.draw_triangle(demo_verticies[15], demo_verticies[13], demo_verticies[12], color=[0,0,0.0], fill=demo_colors[6]) dpg.draw_triangle(demo_verticies[14], demo_verticies[15], demo_verticies[12], color=[0,0,0.0], fill=demo_colors[7]) dpg.draw_triangle(demo_verticies[18], demo_verticies[17], demo_verticies[16], color=[0,0,0.0], fill=demo_colors[8]) dpg.draw_triangle(demo_verticies[19], demo_verticies[17], demo_verticies[18], color=[0,0,0.0], fill=demo_colors[9]) dpg.draw_triangle(demo_verticies[21], demo_verticies[23], demo_verticies[20], color=[0,0,0.0], fill=demo_colors[10]) dpg.draw_triangle(demo_verticies[23], demo_verticies[22], demo_verticies[20], color=[0,0,0.0], fill=demo_colors[11]) with dpg.drawlist(width=500, height=500): with dpg.draw_layer(depth_clipping=False, cull_mode=dpg.mvCullMode_None, perspective_divide=True): dpg.set_clip_space(dpg.last_item(), 0, 0, 500, 500, -1.0, 1.0) with dpg.draw_node(tag="_demo_3dNode3", user_data=[0, 0, 0]): dpg.draw_triangle(demo_verticies[1], demo_verticies[2], demo_verticies[0], color=[0,0,0.0], fill=demo_colors[0]) dpg.draw_triangle(demo_verticies[1], demo_verticies[3], demo_verticies[2], color=[0,0,0.0], fill=demo_colors[1]) dpg.draw_triangle(demo_verticies[7], demo_verticies[5], demo_verticies[4], color=[0,0,0.0], fill=demo_colors[2]) dpg.draw_triangle(demo_verticies[6], demo_verticies[7], demo_verticies[4], color=[0,0,0.0], fill=demo_colors[3]) dpg.draw_triangle(demo_verticies[9], demo_verticies[10], demo_verticies[8], color=[0,0,0.0], fill=demo_colors[4]) dpg.draw_triangle(demo_verticies[9], demo_verticies[11], demo_verticies[10], color=[0,0,0.0], fill=demo_colors[5]) dpg.draw_triangle(demo_verticies[15], demo_verticies[13], demo_verticies[12], color=[0,0,0.0], fill=demo_colors[6]) dpg.draw_triangle(demo_verticies[14], demo_verticies[15], demo_verticies[12], color=[0,0,0.0], fill=demo_colors[7]) dpg.draw_triangle(demo_verticies[18], demo_verticies[17], demo_verticies[16], color=[0,0,0.0], fill=demo_colors[8]) dpg.draw_triangle(demo_verticies[19], demo_verticies[17], demo_verticies[18], color=[0,0,0.0], fill=demo_colors[9]) dpg.draw_triangle(demo_verticies[21], demo_verticies[23], demo_verticies[20], color=[0,0,0.0], fill=demo_colors[10]) dpg.draw_triangle(demo_verticies[23], demo_verticies[22], demo_verticies[20], color=[0,0,0.0], fill=demo_colors[11]) def _demo_live_3D_drawing(): view_matrix = dpg.create_fps_matrix([0, 0, 50], 0.0, 0.0) proj_matrix = dpg.create_perspective_matrix(math.pi*45.0/180.0, 500/500, 0.1, 100) cube_rot = dpg.get_item_user_data("_demo_3dNode1") cube_rot[0] = cube_rot[0] + 1.0 cube_rot[1] = cube_rot[1] + 2.0 cube_rot[2] = cube_rot[2] + 3.0 model_matrix = dpg.create_rotation_matrix(math.pi*cube_rot[0]/180.0 , [1, 0, 0])*\ dpg.create_rotation_matrix(math.pi*cube_rot[1]/180.0 , [0, 1, 0])*\ dpg.create_rotation_matrix(math.pi*cube_rot[2]/180.0 , [0, 0, 1]) dpg.apply_transform("_demo_3dNode1", proj_matrix*view_matrix*model_matrix) dpg.apply_transform("_demo_3dNode2", proj_matrix*view_matrix*model_matrix) dpg.apply_transform("_demo_3dNode3", proj_matrix*view_matrix*model_matrix) dpg.set_item_user_data("_demo_3dNode1", cube_rot) with dpg.item_handler_registry(tag="__demo_item_reg7"): dpg.add_item_visible_handler(callback=_demo_live_3D_drawing) dpg.bind_item_handler_registry("_demo_advanced_drawing_3d", dpg.last_container()) with dpg.collapsing_header(label="Inputs & Events"): with dpg.tree_node(label="Global"): with dpg.handler_registry(show=False, tag="__demo_keyboard_handler"): k_down = dpg.add_key_down_handler(key=dpg.mvKey_A) k_release = dpg.add_key_release_handler(key=dpg.mvKey_A) k_press = dpg.add_key_press_handler(key=dpg.mvKey_A) with dpg.handler_registry(show=False, tag="__demo_mouse_handler"): m_wheel = dpg.add_mouse_wheel_handler() m_click = dpg.add_mouse_click_handler(button=dpg.mvMouseButton_Left) m_double_click = dpg.add_mouse_double_click_handler(button=dpg.mvMouseButton_Left) m_release = dpg.add_mouse_release_handler(button=dpg.mvMouseButton_Left) m_drag = dpg.add_mouse_drag_handler(button=dpg.mvMouseButton_Left) m_down = dpg.add_mouse_down_handler(button=dpg.mvMouseButton_Left) m_move = dpg.add_mouse_move_handler() dpg.add_checkbox(label="Activate Keyboard Handlers (A key)", callback=lambda s, a: dpg.configure_item("__demo_keyboard_handler", show=a)) dpg.add_checkbox(label="Activate Mouse Handlers (left button)", callback=lambda s, a: dpg.configure_item("__demo_mouse_handler", show=a)) kh_down = dpg.add_text("Key id: seconds:", label="Key Down Handler:", show_label=True) kh_release = dpg.add_text("Key id:", label="Key Release Handler:", show_label=True) kh_press = dpg.add_text("Key id:", label="Key Press Handler:", show_label=True) mh_click = dpg.add_text("Mouse id:", label="Mouse Click Handler", show_label=True) mh_double = dpg.add_text("Mouse id:", label="Mouse Double Click Handler", show_label=True) mh_down = dpg.add_text("Mouse id: seconds:", label="Mouse Down Handler", show_label=True) mh_release = dpg.add_text("Mouse id:", label="Mouse Release Handler", show_label=True) mh_wheel = dpg.add_text("Mouse id:", label="Mouse Wheel Handler", show_label=True) mh_move = dpg.add_text("Mouse pos:", label="Mouse Move Handler", show_label=True) mh_drag = dpg.add_text("Mouse id: delta:", label="Mouse Drag Handler", show_label=True) with dpg.tree_node(label="Item"): dpg.add_text("Interact with following widgets and check output!") dpg.add_text("Note: Only the click, hover are added. Others are commented out. Check the code!") cb = dpg.add_checkbox(label="Check me!", tag="democheck") with dpg.item_handler_registry(tag="demoitemregistry"): dpg.add_item_clicked_handler(0, callback=lambda s, a, u: print(f"clicked_handler: {s} '\t' {a} '\t' {u}")) dpg.add_item_clicked_handler(1, callback=lambda s, a, u: print(f"clicked_handler: {s} '\t' {a} '\t' {u}")) dpg.add_item_hover_handler(callback=lambda s, a, u: print(f"hover_handler: {s} '\t' {a} '\t' {u}")) dpg.bind_item_handler_registry(cb, "demoitemregistry") def _event_handler(sender, data): type=dpg.get_item_info(sender)["type"] if type=="mvAppItemType::mvKeyDownHandler": dpg.set_value(kh_down, f"Key id: {data[0]}, Seconds:{data[1]}") elif type=="mvAppItemType::mvKeyReleaseHandler": dpg.set_value(kh_release, f"Key id: {data}") elif type=="mvAppItemType::mvKeyPressHandler": dpg.set_value(kh_press, f"Key id: {data} + Shift: {dpg.is_key_down(dpg.mvKey_LShift)}") elif type=="mvAppItemType::mvMouseClickHandler": dpg.set_value(mh_click, f"Mouse id: {data} + Shift: {dpg.is_key_down(dpg.mvKey_LShift)}") elif type=="mvAppItemType::mvMouseDoubleClickHandler": dpg.set_value(mh_double, f"Mouse id: {data}") elif type=="mvAppItemType::mvMouseDownHandler": dpg.set_value(mh_down, f"Mouse id: {data[0]}, Seconds:{data[1]}") elif type=="mvAppItemType::mvMouseReleaseHandler": dpg.set_value(mh_release, f"Mouse id: {data}") elif type=="mvAppItemType::mvMouseWheelHandler": dpg.set_value(mh_wheel, f"Mouse id: {data}") elif type=="mvAppItemType::mvMouseMoveHandler": dpg.set_value(mh_move, f"Mouse pos: {data}") elif type=="mvAppItemType::mvMouseDragHandler": dpg.set_value(mh_drag, f"Mouse id: {data[0]}, Delta:{[data[1], data[2]]}") for handler in dpg.get_item_children("__demo_keyboard_handler", 1): dpg.set_item_callback(handler, _event_handler) for handler in dpg.get_item_children("__demo_mouse_handler", 1): dpg.set_item_callback(handler, _event_handler) with dpg.collapsing_header(label="Drag & Drop"): with dpg.tree_node(label="Help"): dpg.add_text("Adding a drag_payload to a widget makes it source.", bullet=True) dpg.add_text("Adding a drop_callback to a widget makes it target.", bullet=True) dpg.add_text("Compatibility is determined by the 'payload_type'.", bullet=True) dpg.add_text("The 'payload_type' must be less than 32 characters.", bullet=True) dpg.add_text("A 'drag_callback' can be used to notify a source during a DND event.", bullet=True) dpg.add_text("A 'drag_payload' is a container. Its children are what is shown when dragging.", bullet=True) with dpg.tree_node(label="Simple"): with dpg.group(horizontal=True, xoffset=200): with dpg.group(): dpg.add_text("Int Sources:") dpg.add_button(label="Source 1: 25") with dpg.drag_payload(parent=dpg.last_item(), drag_data=25, payload_type="ints"): dpg.add_text("25") dpg.add_button(label="Source 2: 33") with dpg.drag_payload(parent=dpg.last_item(), drag_data=33, payload_type="ints"): dpg.add_text("33") dpg.add_button(label="Source 3: 111") with dpg.drag_payload(parent=dpg.last_item(), drag_data=111, payload_type="ints"): dpg.add_text("111") with dpg.group(): dpg.add_text("Float Sources:") dpg.add_button(label="Source 1: 43.7") with dpg.drag_payload(parent=dpg.last_item(), drag_data=43.7, payload_type="floats"): dpg.add_text("43.7") dpg.add_button(label="Source 2: 99.8") with dpg.drag_payload(parent=dpg.last_item(), drag_data=99.8, payload_type="floats"): dpg.add_text("99.8") dpg.add_button(label="Source 3: -23.4") with dpg.drag_payload(parent=dpg.last_item(), drag_data=-23.4, payload_type="floats"): dpg.add_text("-23.4") with dpg.group(): dpg.add_text("Targets:") dpg.add_input_int(label="Int Target", payload_type="ints", width=100, step=0, drop_callback=lambda s, a: dpg.set_value(s, a)) dpg.add_input_float(label="Float Target", payload_type="floats", width=100, step=0, drop_callback=lambda s, a: dpg.set_value(s, a)) with dpg.collapsing_header(label="Advanced"): with dpg.tree_node(label="Help (READ ME FIRST)"): dpg.add_text("These topics are for advanced users.", bullet=True) dpg.add_text("Make sure you know what you are doing.", bullet=True) #Can we remove this? with dpg.tree_node(label="Staging"): dpg.add_text("Staging can be used to create items without traditional parents.", bullet=True) dpg.add_text("A stage is a root container that will not attempt to render its children.", bullet=True) dpg.add_text("Regular parent deduction rules still apply.", bullet=True) dpg.add_text("Staging can be useful for wrapping a set of items.", bullet=True) dpg.add_text("You can use most DPG commands on staged items.", bullet=True) dpg.add_text("You can place any item into a stage.", bullet=True) dpg.add_text("Items can be unstaged with 'move_item' and 'unstage'.", bullet=True) dpg.add_text("'unstage' will also delete the stage.", bullet=True) dpg.add_text("A 'stage is a special container that when used with `unstage` will delete itself.", bullet=True) def _unstage_items(sender, app_data, user_data): # push the child back onto the container stack dpg.push_container_stack(user_data[1]) # this will 'unpack' the staging container (regular parent deduction rules apply) dpg.unstage(user_data[0]) # pop the child back off the container stack dpg.pop_container_stack() # when unstaging a stage, it 'unpacks' itself with dpg.stage(tag="__demo_stage1"): dpg.add_button(label="Staged Button 1") dpg.add_button(label="Staged Button 2") dpg.add_button(label="Staged Button 3") ub1 = dpg.add_button(label="Unstage buttons", callback=_unstage_items) child_id = dpg.add_child_window(height=200, width=200) dpg.set_item_user_data(ub1, ["__demo_stage1", child_id]) with dpg.tree_node(label="Manual Mutex Control"): dpg.add_text("DPG has a 'rendering' thread and a 'callback' thread.", bullet=True) dpg.add_text("Only 1 thread can hold the mutex.", bullet=True) dpg.add_text("The rendering thread grabs the mutex right before drawing.", bullet=True) dpg.add_text("The callback thread grabs the mutex when you call a DPG command.", bullet=True) dpg.add_text("If a callback calls multiple DPG commands, they will most likely execute over a few frames.", bullet=True) dpg.add_text("To ensure multiple commands run within the same frame, you can lock/unlock the mutex manually.", bullet=True) staged_container = dpg.generate_uuid() def _callback_auto_mutex(sender, app_data, user_data): for i in range(100): dpg.add_text("Item: " + str(i), parent=user_data) def _callback_manual_mutex(sender, app_data, user_data): dpg.lock_mutex() # you could also use with dpg.mutex() dpg.push_container_stack(dpg.add_stage(id=staged_container)) for i in range(100): dpg.add_text("Item: " + str(i)) dpg.pop_container_stack() dpg.unlock_mutex() dpg.set_item_children(user_data, staged_container, 1) with dpg.group(horizontal=True): b1 = dpg.add_button(label="Add 100 items") b2 = dpg.add_button(label="Add 100 items (mutex)") b3 = dpg.add_button(label="Delete Items", callback=lambda s, a, u: dpg.delete_item(u, children_only=True)) dpg.add_child_window(height=500, width=-1) dpg.configure_item(b1, user_data=dpg.last_item(), callback=_callback_auto_mutex) dpg.configure_item(b2, user_data=dpg.last_item(), callback=_callback_manual_mutex) dpg.configure_item(b3, user_data=dpg.last_item()) if dpg.get_platform() == dpg.mvPlatform_Windows or dpg.get_platform() == dpg.mvPlatform_Linux: with dpg.tree_node(label="Output Framebuffer"): def _framebuffer_callback(sender, app_data): dpg.show_item("__demo_texture_container") dpg.add_dynamic_texture(app_data.get_width(), app_data.get_height(), app_data, parent="__demo_texture_container") dpg.add_text("Outputs frame buffer an mvBuffer object, creates a dynamic texture, and shows the texture registry (check final item)") dpg.add_button(label="Output Framebuffer", callback=lambda:dpg.output_frame_buffer(callback=_framebuffer_callback)) if __name__ == '__main__': import dearpygui.dearpygui as dpg dpg.create_context() dpg.create_viewport(title='Custom Title', width=600, height=600) show_demo() dpg.setup_dearpygui() dpg.show_viewport() dpg.start_dearpygui() dpg.destroy_context()