Skip to content

subplots with linked x-axis having a slightly off range #646

@proptrader33

Description

@proptrader33

I have two subplots that are supposed to have their x-axis range linked together so that upon mouse drag event or mouse wheel event while the mouse is inside either of them, the other will move at the same time.

I've noticed that both types of mouse events correctly synchronize the subplots when the mouse is inside the first subplot, but when the mouse is inside the second subplot, the wheel events are not handled properly and will lead to two the first subplot's x-axis range being slightly off (the drag events seem to be handled properly though).

The following is a minimal setup demonstrating this bug, which is ready to be copy-paste and run right away.

void refresh() {
  static float xs[1000], ys1[1000], ys2[1000];
  static bool initialized{false};
  if (!initialized) {
    for (int i = 0; i < 1000; ++i) {
      xs[i] = i * 0.01f;
      ys1[i] = sinf(xs[i]);
      ys2[i] = cosf(xs[i]);
    }
    initialized = true;
  }

  ImGui::Begin("Synchronized X-Axis Example");

  static int count{0};
  ImPlot::PushColormap(ImPlotColormap_Deep);
  println("================================================================================");
  if (ImPlot::BeginSubplots("SyncedPlots", 2, 1, ImVec2(-1, 400), ImPlotSubplotFlags_LinkCols)) {

    // Draw the first subplot.
    if (ImPlot::BeginPlot("Plot 1")) {
      auto xRange1{ImPlot::GetPlotLimits().X};
      println(count, " plot1.hovered? ", ImPlot::IsPlotHovered(), ",", ImPlot::IsSubplotsHovered());
      println(count, " plot1.xrange1: ", xRange1.Min, "-", xRange1.Max);
      ImPlot::PlotLine("sin(x)", xs, ys1, 1000);
      auto xRange2{ImPlot::GetPlotLimits().X};
      println(count, " plot1.xrange2: ", xRange2.Min, "-", xRange2.Max);
      ImPlot::EndPlot();
    }
    
    // Draw the second subplot.
    if (ImPlot::BeginPlot("Plot 2")) {
      println(count, " plot2.hovered? ", ImPlot::IsPlotHovered(), ",", ImPlot::IsSubplotsHovered());
      auto xRange1{ImPlot::GetPlotLimits().X};
      println(count, " plot2.xrange1: ", xRange1.Min, "-", xRange1.Max);
      ImPlot::PlotLine("cos(x)", xs, ys2, 1000);
      auto xRange2{ImPlot::GetPlotLimits().X};
      println(count, " plot2.xrange2: ", xRange2.Min, "-", xRange2.Max);
      count++;
      ImPlot::EndPlot();
    }
    ImPlot::EndSubplots();
  }
  ImPlot::PopColormap();
  ImGui::End();
}

int main() {
  // Setup window.
  glfwSetErrorCallback([](int error, const char* description) {
    fprintf(stderr, "GLFW Error %d: %s\n", error, description);
  });
  if (!glfwInit()) {
    abort();
  }
  glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);

  // Create window with graphics context.
  GLFWwindow* window{glfwCreateWindow(1280, 720, "ManualTPlatform", nullptr, nullptr)};
  if (window == nullptr) {
    fprintf(stderr, "Failed to initialize GLFW window!\n");
    abort();
  }
  glfwMakeContextCurrent(window);
  glfwSwapInterval(0);
  if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) {
    err("Failed to initialize GLAD");
    return -1;
  }

  // Setup Dear ImGui & ImPlot contexts.
  IMGUI_CHECKVERSION();
  ImGui::CreateContext();
  ImPlot::CreateContext();
  ImGui_ImplGlfw_InitForOpenGL(window, true);
  ImGui_ImplOpenGL3_Init("#version 130");

  ImVec4 clearColor{0.0f, 0.0f, 0.0f, 1.0f};
  while (!glfwWindowShouldClose(window)) {
    glfwWaitEvents();

    // Start a new frame.
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();

    // Update the GUI.
    refresh();

    // Render.
    ImGui::Render();
    int w, h;
    glfwGetFramebufferSize(window, &w, &h);
    glViewport(0, 0, w, h);
    glClearColor(clearColor.x, clearColor.y, clearColor.z, clearColor.w);
    glClear(GL_COLOR_BUFFER_BIT);
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
    glfwSwapBuffers(window);
  }
  return 1;
}

The following is an example console output produced when I use the mouse wheel to zoom out when the mouse is inside the second subplot:

================================================================================
64  plot1.hovered?  0 , 1
64  plot1.xrange1:  0.114185 - 0.954463
64  plot1.xrange2:  0.114185 - 0.954463
64  plot2.hovered?  1 , 1
64  plot2.xrange1:  0.164245 - 0.9345
64  plot2.xrange2:  0.164245 - 0.9345

Notice how the first subplot's xrange is 0.114185 - 0.954463 but the second subplot's xrange is 0.164245 - 0.9345.

The difference is also visible in the charts themselves too. Notice in the following screenshot how the x-range does not match between the two subplots:

Image

This bug occurs with both the actual wheel of a mouse (a wheel that rotates in discrete steps) and the virtual wheel events of the touchpad of a laptop.

Metadata

Metadata

Labels

prio:lowLow prioritystatus:doingWork is currently in progresstype:fixSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions