GeezerVison is showing github.com — Legends · Issue #403 · fastplotlib/fastplotlib
DescriptionIt's time to add legends 😄 ! Laying out ideas first, with some inspiration from pyqtgraph
Basics
Multiple legends will be allowed in a Subplot or Dock. They can exist in moveable and non-moveable states.
A Legend is created and then graphics can be added to it:
import fastplotlib as fpl
plot = fpl.Plot()
line_a = plot.add_line(line_data, name="A")
# create a legend
legend = fpl.Legend(plot_area=plot.docks["top"]) # can also just be `plot`
# add a "legend item" by adding the graphic to the legend
# this adds a graphical item to the legend along with text that corresponds to the graphic
legend.add_graphic(line_a, label=None) # if label is None, uses graphic name to set the label
All legend items will auto add event handlers to relevant graphic features so that they are automatically updated.
Line collections or scatters
For line collections, use a standard legend if a qualitative colormap was used.
line_coll = plot.add_line_collection(data, colors="tab10")
# use the same legend box or create a new one
legend.add_graphic(line_coll, labels=["B", "B", "C", "C", "D"]) # label for each line in the collection, legend only contains unique labels
If a quantitative cmap is used, use colorbars instead
line_coll_jet = plot.add_line_collection(data, colors="jet") # quantitative cmap
cbar = fpl.Colorbar(plot_area=plot.docks["top"])
cbar.add_graphic(line_coll_jet) # colorbar if quantitative data are used for lines and scatter
Other cool features :D
Click on legend item's line, highlights corresponding graphic. Just use the feature event handlers. Click anywhere else in the legend to deactivate the highlight.
More thoughts:
- I think we should enforce unique labels among all
LegendItems within a single Legend. Legends don't really make sense anyways if their entries aren't unique?
- If there are multiple colors along a single line:
- If it is quantitative make a colorbar.
- If it is qualitative make a legend with an item for each color?
- For
LineCollection, do we need to do a sanity check to make sure that when a user passes labels, that these lines all have the same color? Likewise for other aspects like line thickness.
- For scatter, there can be different colors and sizes too, so that will also have to be dealt with just like qualitative vs. quantitative cmaps.
- ImageGraphic Colorbars are made per-ImageGraphic, and auto-made and placed next to the HistogramLUTWidget when present.
- For colorbars allow displaying just min and max, or min and max with ticks and spaced out tick labels.
- How to deal with changes? If graphic features change that's easy, our event handlers. What about larger scale changes? If the labels change for a line collection but we still have a 1 -> 1 direct mapping from old to new labels. What if the grouping of the new labels is completely diff? For example, if we colored a line collection based on neuron ID and then based on brain region, and then based on behavior?
Activitykushalkolar commented on Feb 23, 2024 Ideas with Edoardo:
Single, multiple or line collection with qualitative colors, make a legend with all unique colors.
But how to set the labels per color?
- One idea: dict of
{cmap_value: label}
{rgba_color: label}
- pass this dict to
label arg in Legend.add_graphic()
Maybe allow user to make the choice of legend vs. colorbar for lines. kushalkolar commented on Feb 29, 2024 Get the bbox of the scene, if it's > 0 then make the legend ~25% the size of the scene? kushalkolar commented on Sep 12, 2026 I Just got an idea, Graphics control how they appear in a legend. So you give a Graphic a legend, and it creates a LegendItem that it controls. I think this makes it easier. kushalkolar commented on Sep 17, 2026 Legends with Imgui:
- A
Graphic manages its own LegendItem. Graphic.create_legend_item(), creates a legend item instance that is a property of the Graphic, it stays on the graphic and when the graphic changes, the legend item also changes its representation. So it's a mini MVC.
- For lines and scatters, only support uniform colors and cmap uses a colorbar for quantitative colormap transforms. The user provides legend labels for each transform value if it's a quantitative colormap. Per-vertex colors are NOT supported with a legend item because that's way too arbitrary and undefined, we spit out a warning.
- For multi lines when using visibility selector the graphic needs to have some notion of know it has a selection on it so the legend item represents the current selection.
- Not supported and raises: scatter modes other than "marker".
- Labels:
- For uniform colors and uniform markers (scatter), use the graphic's name and keep it synced
- For colormap and quantitative values, also use the graphic's name and allow a name for the vmin, vmax.
- For colormap and qualitative/categorical values, the user must specify legend labels explicitly by mapping the transform values to the label. Use at collection level and per-graphic level.
- for scatters, provide mapping of marker shape -> label
- if multi, e.g. color + marker, the label is just concatenated
Graphic's create AND manage a LegendItem, these are given to imgui which just draws and does the layouting etc. TGBoat000 commented on Oct 18, 2026 @kushalkolar
Hi! Would it make sense to support clicking legend items to cycle the associated graphic through three states: normal, highlighted, and hidden?
Highlighting could make the graphic more prominent, for example by increasing the line thickness or scatter marker size. Hiding would set graphic.visible = False, while keeping the legend item visible and clickable so the graphic can be restored.
The cycle would be: normal → highlighted → hidden → normal, with the original appearance restored when returning to normal. kushalkolar commented on Oct 19, 2026
9. @kushalkolar
Hi! Would it make sense to support clicking legend items to cycle the associated graphic through three states: normal, highlighted, and hidden?
Highlighting could make the graphic more prominent, for example by increasing the line thickness or scatter marker size. Hiding would set graphic.visible = False, while keeping the legend item visible and clickable so the graphic can be restored.
The cycle would be: normal → highlighted → hidden → normal, with the original appearance restored when returning to normal.
@FlynnOConnell what do you think?
My main thing is that highlights be done with the HighlightSelector or some other form of shader injection for this purpose instead of changing the main buffer for the graphic feature. FlynnOConnell commented on Oct 19, 2026 @TGBoat000
If you're talking about something like this, where you can hide individual legend items, fully in support of this.
screenrecording-2026-10-18_21-26-01.mp4
Not sure about highlighting the graphic feature though. I don't see the need, do you have a use case? kushalkolar commented on Oct 19, 2026 I guess mouse over highlight could make sense TGBoat000 commented on Oct 20, 2026 Thanks for the feedback. @kushalkolar @FlynnOConnell
Yes, the behavior shown in the video is exactly what I had in mind for toggling visibility.
I also support the idea of highlighting on hover. I work in robotics and would like to use fastplotlib to visualize robot joint position, velocity, and current data, including both planned trajectories and actual feedback. Sometimes these curves overlap, making it difficult to distinguish them. Hover highlighting would make it easier to identify a specific curve without hiding the others.
I'd be happy to start working on a PR in a few days. kushalkolar commented on Oct 20, 2026 If you make a PR please do make an issue first outlining the plan and implementation. We can review your PR but our bandwidth is spread across many projects right now.
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|