DearPyGui icon indicating copy to clipboard operation
DearPyGui copied to clipboard

Does it support polygon frames

Open monkeycc opened this issue 1 year ago • 9 comments

微信截图_20241224004008 微信截图_20241224004508

polygon

monkeycc avatar Dec 23 '24 16:12 monkeycc

It's not clear what you mean or what help you might need. Would you please provide a detailed description of your issue?

v-ein avatar Dec 25 '24 09:12 v-ein

https://github.com/user-attachments/assets/0a79b4dc-b76d-40bc-b047-607f91016a99

  1. Implement polygon frame function with mouse
  2. Polygons can be edited

monkeycc avatar Dec 25 '24 09:12 monkeycc

Well, that's something you have to do on your own :joy:. If you need some ideas on how this can be implemented, here's an example I recently made for a question asked on Discord.

from math import sin
import dearpygui.dearpygui as dpg

dpg.create_context()
dpg.create_viewport(title=f"Test - {dpg.get_dearpygui_version()}", width=700, height=750)

def on_point_dragged(drag_point, app_data, idx):
    new_x, new_y = dpg.get_value(drag_point)
    xs, ys, *_ = dpg.get_value("line-series")
    # Uncomment this if you need X to be clamped between the neighbour points
    # if idx > 0 and new_x < xs[idx - 1]:
    #     new_x = xs[idx - 1]
    #     dpg.set_value(drag_point, (new_x, new_y))
    # elif idx < len(xs) - 1 and new_x > xs[idx + 1]:
    #     new_x = xs[idx + 1]
    #     dpg.set_value(drag_point, (new_x, new_y))

    xs[idx] = new_x
    ys[idx] = new_y
    dpg.set_value("line-series", (xs, ys))

with dpg.window() as wnd:
    dpg.set_primary_window(dpg.last_item(), True)

    x_data = [x/3 for x in range(0, 30)]
    y_data = [sin(x) for x in x_data]

    with dpg.theme() as marker_theme:
        with dpg.theme_component():
            dpg.add_theme_style(dpg.mvPlotStyleVar_Marker, dpg.mvPlotMarker_Circle, category=dpg.mvThemeCat_Plots)

    with dpg.plot(width=-1, height=-1, tag="plot"):
        x_axis = dpg.add_plot_axis(dpg.mvXAxis, label="x")
        with dpg.plot_axis(dpg.mvYAxis, label="y", no_label=True) as y_axis:
            dpg.add_line_series(x_data, y_data, label="Line series", tag="line-series")
            dpg.bind_item_theme(dpg.last_item(), marker_theme)

        for i, (x, y) in enumerate(zip(x_data, y_data)):
            dpg.add_drag_point(label="", default_value=(x, y), callback=on_point_dragged, user_data=i, color=(0, 0, 0, 0))

dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()

v-ein avatar Dec 25 '24 12:12 v-ein

wow Thank you so much for your help

As long as there is code reference I will make changes

Thank you very much for your help

monkeycc avatar Dec 25 '24 12:12 monkeycc

Image

Hello, I found this issue after modifying your code based on it How to remove excess filling ?

from math import sin
import dearpygui.dearpygui as dpg
import math

dpg.create_context()
dpg.create_viewport(title=f"Test - {dpg.get_dearpygui_version()}", width=700, height=750)

def on_point_dragged(drag_point, app_data, idx):
    new_x, new_y = dpg.get_value(drag_point)
    xs, ys, *_ = dpg.get_value("line-series")
    # Uncomment this if you need X to be clamped between the neighbour points
    # if idx > 0 and new_x < xs[idx - 1]:
    #     new_x = xs[idx - 1]
    #     dpg.set_value(drag_point, (new_x, new_y))
    # elif idx < len(xs) - 1 and new_x > xs[idx + 1]:
    #     new_x = xs[idx + 1]
    #     dpg.set_value(drag_point, (new_x, new_y))

    xs[idx] = new_x
    ys[idx] = new_y
    dpg.set_value("line-series", (xs, ys))

with dpg.window() as wnd:
    dpg.set_primary_window(dpg.last_item(), True)

    num_points = 10  
    radius = 5  
    theta = [2 * math.pi * i / num_points for i in range(num_points)]
    x_data = [radius * math.cos(t) for t in theta]
    y_data = [radius * math.sin(t) for t in theta]


    with dpg.plot(width=-1, height=-1, tag="plot"):
        x_axis = dpg.add_plot_axis(dpg.mvXAxis, label="x")
        with dpg.plot_axis(dpg.mvYAxis, label="y") as y_axis:
            dpg.add_line_series(x_data, y_data, label="Circle", tag="line-series",shaded=True)

        for i, (x, y) in enumerate(zip(x_data, y_data)):
            dpg.add_drag_point(label="", default_value=(x, y), callback=on_point_dragged, user_data=i, color=(0, 0, 0, 0))

dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()

monkeycc avatar Jan 17 '25 12:01 monkeycc

shaded=True makes line_series behave much the same way as shade_series: it fills the space between the line and the X axis. It doesn't suit for drawing arbitrary filled polygons.

I believe you can use draw_polygon in place of line_series to do what you need.

v-ein avatar Jan 17 '25 15:01 v-ein

Well.. turns out that #2045 ruins the idea of using draw_polygon to render a filled polygon.

v-ein avatar Jan 17 '25 16:01 v-ein

Another option is add_area_series in place of add_line_series:

dpg.add_area_series(x_data, y_data, tag="line-series", fill=(255, 255, 255, 255))

Works just fine.

v-ein avatar Jan 17 '25 16:01 v-ein

https://github.com/user-attachments/assets/f92f7530-af56-4ebe-90a0-c92d7288a5db

Thanks for your help Without your help, I couldn't have completed these functions

Thank you again

monkeycc avatar Jan 18 '25 02:01 monkeycc