Skip to content

feat: Add spans for plots - #152

Closed
azerupi wants to merge 1 commit into
emilk:mainfrom
azerupi:feature/spans
Closed

feat: Add spans for plots#152
azerupi wants to merge 1 commit into
emilk:mainfrom
azerupi:feature/spans

Conversation

@azerupi

@azerupi azerupi commented Nov 16, 2025

Copy link
Copy Markdown
Contributor

This PR adds supports for spans in plots on either axis. This allows for example to highlight a region of interest or draw states in the background of plots.

image

There are a few points I would like to highlight that would need some feedback:

  1. The spans are drawn as plot items and therefore they show up in the legend. The structure in the code makes sense but I'm not sure if the spans should be displayed in the legend. With a lot of spans on a plot this could become quite messy. The name of the spans are displayed in the plot themselves already.
  2. The names of the spans are drawn in over them for spans on the x-axis they are drawn at the top-center of the span and for spans on the y-axis they are drawn at the left-middle of the span. When zooming out and the span is too small to display the name it will get truncated and ultimately hidden. I think this looks good and is functional, but this is all very arbitrary so I'm open for other solutions.
  3. The spans being plot items means that they also get drawn in the order they are called in the show closure. This means it could be drawn on top of the line plot. This has advantages and disadvantages. I'm not sure if we want to have spans always be drawn in the background of other plot items?

@michalsustr michalsustr left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@azerupi thanks for the PR, it's very useful!

Feedback:

  1. The spans are drawn as plot items and therefore they show up in the legend. The structure in the code makes sense but I'm not sure if the spans should be displayed in the legend. With a lot of spans on a plot this could become quite messy. The name of the spans are displayed in the plot themselves already.

Agreed. I think it rather makes sense to implement them as PlotItems than the current PlotItemBase.
There is a similar implementation in this fork: 0xb-s#39 (for inspiration) but I think yours is better because of the labels.

  1. The names of the spans are drawn in over them for spans on the x-axis they are drawn at the top-center of the span and for spans on the y-axis they are drawn at the left-middle of the span. When zooming out and the span is too small to display the name it will get truncated and ultimately hidden. I think this looks good and is functional, but this is all very arbitrary so I'm open for other solutions.

I like it! <3

  1. The spans being plot items means that they also get drawn in the order they are called in the show closure. This means it could be drawn on top of the line plot. This has advantages and disadvantages. I'm not sure if we want to have spans always be drawn in the background of other plot items?

I believe spans should be drawn in the background, and other plot items should be overlayed. If it was photoshop layers, I'd make it 0. background (ticks etc), 1. spans 2. plot items (lines, markers, etc.)

Other things that would be great to add:

  • Ability to choose the vertical/horizontal placement of the labels.
  • Semiopen intervals: allow +/- inf spans.

rect_elem::highlighted_color,
};

const LABEL_PADDING: f32 = 4.0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add doc comment, which sides the padding applies to (I think all?)

Comment thread egui_plot/src/items/span.rs Outdated

// If the span is too small to display the full name, find the longest name
// with "..." appended that we can display within the span
fn find_name_candidate(&self, width: f32, painter: &Painter, font_id: &FontId) -> String {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's extract this as a standalone util function, it can be used in other places.

@azerupi

azerupi commented Nov 21, 2025

Copy link
Copy Markdown
Contributor Author

Thank you @michalsustr! This is great feedback and exactly what I was looking for.
Everything you said makes sense to me. I'll try to work on this over the next 10 days.

@michalsustr

Copy link
Copy Markdown
Collaborator

Great, looking forward!

@michalsustr michalsustr self-assigned this Nov 22, 2025
@michalsustr michalsustr changed the title Add spans for plots feat: Add spans for plots Nov 22, 2025
@michalsustr

Copy link
Copy Markdown
Collaborator

I was working on the code base over the weekend and got more familiar with it. I changed my mind: I think it should keep being PlotItem as you've done it. What should be done instead is each item should declare if it should be shown in the legend. This is for another independent PR. So please ignore that, and we can finish the PR as it is, without too many changes (just the two little features I outlined). Thank you!

@azerupi

azerupi commented Nov 23, 2025

Copy link
Copy Markdown
Contributor Author

Sounds good!

@azerupi

azerupi commented Nov 23, 2025

Copy link
Copy Markdown
Contributor Author

@michalsustr just to be sure, you still want me to draw the spans on in the background even if we keep them as PlotItem? Is there a way to do this or would this require a new mechanism or workaround?

@michalsustr

michalsustr commented Nov 24, 2025

Copy link
Copy Markdown
Collaborator

just to be sure, you still want me to draw the spans on in the background even if we keep them as PlotItem? Is there a way to do this or would this require a new mechanism or workaround?

You can keep the current implementation with impl PlotItem as it is. Just please address the PR comments and two features, thank you so much!

@azerupi

azerupi commented Nov 28, 2025

Copy link
Copy Markdown
Contributor Author

@michalsustr I believe I implemented the changes you asked for.

  1. I've added a way to provide an Align2 to place the label through the label_align() method. There is one thing to call out here. To make it more convenient when calling axis() to choose if it should be an x- or y-axis span it will also set the align to the default for that axis. This avoids the user having to call label_align(). However that means that any call to label_align() should be done after calls to axis() because otherwise it would overwrite the alignment set by the user. I have documented this behavior in both methods. Let me know if you prefer that I remove this side-effect and have the user call align_label() explicitly when changing the axis.

  2. I've extended support for infinite spans. For this to work I had to change the bounds returned by spans to not impact the plot bounds. This means that spans will not have any effect on auto bounds. I believe this is the right thing to do, however I didn't figure out how to set the initial default bounds in the example. If I set default bounds on the plot it seems to disable the ability to zoom & pan the plot which I think is very desirable for the example. Do you know how I can set the bounds so that all spans are visible by default but still allow zooming and panning?

  3. I've extracted out the function that truncates the labels for a given width. I didn't know where to put it, so I added a utils module. If you have a better place for it, let me know.

  4. We could make the padding/margin of the labels configurable instead of being hard-coded. But I didn't want to add too much complexity in this PR.

@michalsustr

Copy link
Copy Markdown
Collaborator
  1. However that means that any call to label_align() should be done after calls to axis() because otherwise it would overwrite the alignment set by the user.

I think that is reasonable, thank you for pointing it out!

  1. [..] This means that spans will not have any effect on auto bounds. I believe this is the right thing to do

Me too.

  1. [..] Do you know how I can set the bounds so that all spans are visible by default but still allow zooming and panning?

I would leave it as it is for now. I plan to work on bounds soon, as I am not happy with the current design, exactly for the reasons you outlined.

  1. I didn't know where to put it, so I added a utils module.

That's good, thank you!

  1. We could make the padding/margin of the labels configurable instead of being hard-coded. But I didn't want to add too much complexity in this PR.

Agreed, this can be done in other PRs.

@michalsustr

Copy link
Copy Markdown
Collaborator

I will try to rebase this PR on the latest changes of the demo gallery.

@michalsustr

Copy link
Copy Markdown
Collaborator

Hi @bircni ! I rebased the PR on main, due to large number of changes in demo gallery. But I couldn't edit this PR because it required pushing to git lfs, and I don't have access to your repo. So I opened a new one: #196 and going to merge it soon. Sorry for the complications, and thank you for the contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add vertical and horizontal spans to plots

2 participants