hoffstadt / DearPyGui

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

Plot legend color is not updated according to theme color #1610

Open mkouhia opened 2 years ago

mkouhia commented 2 years ago

Version of Dear PyGui

Version: 1.3.1 Operating System: Windows 10

My Issue/Question

When a plot scatter series is themed, chosen color is not displayed on the legend. Instead, some default series colour is displayed. The theme colour is properly employed in the plot area itself.

To Reproduce

Steps to reproduce the behavior:

  1. Run example code
  2. Look at colour of plot legend entry for scatter series. It is blue, but it should be red. Stem series colour is updated in the legend correctly.

Expected behavior

The colour that is set by dpg.add_theme_color should be displayed in the legend.

Screenshots/Video

image

Standalone, minimal, complete and verifiable example

The example code is from documentation, https://dearpygui.readthedocs.io/en/latest/documentation/plots.html#colors-and-styles -- only colour of scatter series is changed to red in order to highlight the problem.

import dearpygui.dearpygui as dpg
from math import sin

dpg.create_context()

sindatax = []
sindatay = []
for i in range(0, 100):
    sindatax.append(i / 100)
    sindatay.append(0.5 + 0.5 * sin(50 * i / 100))
sindatay2 = []
for i in range(0, 100):
    sindatay2.append(2 + 0.5 * sin(50 * i / 100))

with dpg.window(label="Tutorial", width=500, height=400):
    # create a theme for the plot
    with dpg.theme(tag="plot_theme"):
        with dpg.theme_component(dpg.mvStemSeries):
            dpg.add_theme_color(dpg.mvPlotCol_Line, (150, 255, 0), category=dpg.mvThemeCat_Plots)
            dpg.add_theme_style(dpg.mvPlotStyleVar_Marker, dpg.mvPlotMarker_Diamond, category=dpg.mvThemeCat_Plots)
            dpg.add_theme_style(dpg.mvPlotStyleVar_MarkerSize, 7, category=dpg.mvThemeCat_Plots)

        with dpg.theme_component(dpg.mvScatterSeries):
            dpg.add_theme_color(dpg.mvPlotCol_Line, (217, 95, 2), category=dpg.mvThemeCat_Plots)
            dpg.add_theme_style(dpg.mvPlotStyleVar_Marker, dpg.mvPlotMarker_Square, category=dpg.mvThemeCat_Plots)
            dpg.add_theme_style(dpg.mvPlotStyleVar_MarkerSize, 4, category=dpg.mvThemeCat_Plots)

    # create plot
    with dpg.plot(tag="plot", label="Line Series", height=-1, width=-1):

        # optionally create legend
        dpg.add_plot_legend()

        # REQUIRED: create x and y axes
        dpg.add_plot_axis(dpg.mvXAxis, label="x")
        dpg.add_plot_axis(dpg.mvYAxis, label="y", tag="yaxis")

        # series belong to a y axis
        dpg.add_stem_series(sindatax, sindatay, label="0.5 + 0.5 * sin(x)", parent="yaxis", tag="series_data")
        dpg.add_scatter_series(sindatax, sindatay2, label="2 + 0.5 * sin(x)", parent="yaxis", tag="series_data2")

        # apply theme to series
        dpg.bind_item_theme("series_data", "plot_theme")
        dpg.bind_item_theme("series_data2", "plot_theme")

dpg.create_viewport(title='Custom Title', width=800, height=600)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
Hermueller commented 5 months ago

I just encountered a similar issue with the _customseries where the legend had black icons for all data series. And this is what I found out and the hotfix for it.

Scatter Series

The _scatterseries seems to be using the mvPlotCol_MarkerOutline for the legend coloring.
When you changed the color of the mvPlotCol_Line it changed the filling to your specified color and disabled the outline but kept the original color of the outline in the background stored. Therefore, it still accessed the original color.

As a fix, you could additionally set the mvPlotCol_MarkerOutline.

So instead of

with dpg.theme_component(dpg.mvScatterSeries):
    dpg.add_theme_color(dpg.mvPlotCol_Line, (217, 95, 2), category=dpg.mvThemeCat_Plots)
    dpg.add_theme_style(dpg.mvPlotStyleVar_Marker, dpg.mvPlotMarker_Square, category=dpg.mvThemeCat_Plots)
    dpg.add_theme_style(dpg.mvPlotStyleVar_MarkerSize, 4, category=dpg.mvThemeCat_Plots)

you would have

with dpg.theme_component(dpg.mvScatterSeries):
    dpg.add_theme_color(dpg.mvPlotCol_Line, (217, 95, 2), category=dpg.mvThemeCat_Plots)
    dpg.add_theme_color(dpg.mvPlotCol_MarkerOutline, (217, 95, 2), category=dpg.mvThemeCat_Plots)
    dpg.add_theme_style(dpg.mvPlotStyleVar_Marker, dpg.mvPlotMarker_Square, category=dpg.mvThemeCat_Plots)
    dpg.add_theme_style(dpg.mvPlotStyleVar_MarkerSize, 4, category=dpg.mvThemeCat_Plots)

Custom Series

If someone stumbles upon the issue of not having color legends for the custom_series, here is what I found out in case someone needs it:

Setting any of the mvPlot variables does nothing.
My hotfix that works is creating an empty scatter_series that uses the same internal_labels so that the custom_series and scatter_series are grouped together and, therefore, the mvPlot variables from the scatter_series are used for the legend instead:

with dpg.window(label="Tutorial") as win:
    # create a theme for the plot
    with dpg.theme(tag="plot_theme"):
        with dpg.theme_component(dpg.mvAll):
            dpg.add_theme_color(dpg.mvPlotCol_MarkerOutline, (150, 255, 10, 255), category=dpg.mvThemeCat_Plots)

    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, tag="yaxis"):
            with dpg.custom_series(x_data, y_data, 2, label="Custom Series", callback=callback, tag="demo_custom_series", use_internal_label=False):
                dpg.add_text("Current Point: ", tag="custom_series_text")
            dpg.fit_axis_data(dpg.top_container_stack())
        dpg.add_scatter_series([], [], label="Custom Series", parent="yaxis", tag="series_data", use_internal_label=False)
        dpg.bind_item_theme("series_data", "plot_theme")

The rest of the missing code is just the demo example for the custom_series given on the dearpygui website.