Auto resize with linked axis
I can't seem to get linked axis working to automatically scale once I have received data. I need to auto scale the X axis for 2 Plots that are linked, but Auto scale the Y values. When I load data, it doesn't automatically fit the plots. It places them about half way across the axis, but then when I double click it it scales it properly.
ImPlot::LinkNextPlotLimits(&Get_Instance().m_Line_X_Min, &Get_Instance().m_Line_X_Max, NULL, NULL);
if (Get_Instance().m_ResizeLinePlot) { Get_Instance().m_ResizeLinePlot = false; ImPlot::FitNextPlotAxes(); }
if (ImPlot::BeginPlot("Line Graph##Line", "Day", "AUD", ImVec2(-1, 0), ImPlotFlags_NoBoxSelect | ImPlotFlags_AntiAliased, ImPlotAxisFlags_Time, ImPlotAxisFlags_AutoFit | ImPlotAxisFlags_RangeFit)) {
//Plot line graph here
ImPlot::EndPlot();
}
ImPlot::LinkNextPlotLimits(&Get_Instance().m_Line_X_Min, &Get_Instance().m_Line_X_Max, NULL, NULL);
if (ImPlot::BeginPlot("Bar Graph##Line", "Day", NULL, ImVec2(-1, 0), ImPlotFlags_NoLegend | ImPlotFlags_NoBoxSelect | ImPlotFlags_AntiAliased, ImPlotAxisFlags_Time, ImPlotAxisFlags_AutoFit | ImPlotAxisFlags_RangeFit)) {
//Plot a bar graph here
ImPlot::EndPlot();
}
Get_Instance() just allows me to access member variables. m_ResizeLinePlot gets set to true when I load the data.
Can you recreate the issue with dummy data in a minimal working example I can compile and test?
#include <GL/glew.h>
#ifndef GLFW_INCLUDE_NONE
#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors.
#endif // GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include "ImGui/imgui.h"
#include "ImGui/implot.h"
#include "ImGui/implot_internal.h"
#include "ImGui/imgui_impl_glfw.h"
#include "ImGui/imgui_impl_opengl3.h"
#include <iostream>
#include <vector>
static void LoadData(std::vector< double >* xData, std::vector< double >* yData)
{
//srand(time(0));
double randMax = 100;
xData->resize(5000);
yData->resize(5000);
for (int i = 0; i < 5000; i++) {
xData->at(i) = 86400 * i + 852163200;
yData->at(i) = ((double)rand() / (double)(RAND_MAX)) * randMax;
}
}
int main(int argc, char* argv[])
{
bool resizeLinePlot = false;
double lineXMin, lineXMax;
int windowWidth = 1280;
int windowHeight = 720;
char fps[10];
std::vector< double > xData, yData;
glfwInit();
const char* glslVersion = "#version 460";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
// Create window with graphics context
GLFWwindow* window = glfwCreateWindow(windowWidth, windowHeight, "Program", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSwapInterval(0); // vsync
//Initialize GLEW + ImGui
glewInit();
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImPlot::CreateContext();
// Setup Dear ImGui style
ImGui::StyleColorsDark();
ImPlotStyle& ImPlot_Style = ImPlot::GetStyle();
ImPlot_Style.UseLocalTime = true;
ImPlot_Style.AntiAliasedLines = true;
// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init(glslVersion);
ImGui::GetIO().Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\Arial.ttf", 21.0f);
while (!glfwWindowShouldClose(window))
{
//Events
glfwPollEvents();
// Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui::Begin("Graphs");
if (ImGui::Button("LoadData")) {
LoadData(&xData, &yData);
resizeLinePlot = true;
}
ImPlot::LinkNextPlotLimits(&lineXMin, &lineXMax, NULL, NULL);
if (resizeLinePlot) { resizeLinePlot = false; ImPlot::FitNextPlotAxes(); }
if (ImPlot::BeginPlot("Line Graph##Line", "Day", "AUD", ImVec2(-1, 0), ImPlotFlags_NoBoxSelect | ImPlotFlags_AntiAliased, ImPlotAxisFlags_Time, ImPlotAxisFlags_AutoFit | ImPlotAxisFlags_RangeFit)) {
ImPlot::PlotLine("Line Graph##Data", xData.data(), yData.data(), yData.size());
ImPlot::EndPlot();
}
ImPlot::LinkNextPlotLimits(&lineXMin, &lineXMax, NULL, NULL);
if (ImPlot::BeginPlot("Bar Graph##Line", "Day", NULL, ImVec2(-1, 0), ImPlotFlags_NoLegend | ImPlotFlags_NoBoxSelect | ImPlotFlags_AntiAliased, ImPlotAxisFlags_Time, ImPlotAxisFlags_AutoFit | ImPlotAxisFlags_RangeFit)) {
for (int i = 0; i < xData.size(); i++) {
if (i == 0) {
ImPlot::PushStyleColor(ImPlotCol_Line, ImVec4(0, 1, 0, 1));
ImPlot::PushStyleColor(ImPlotCol_Fill, ImVec4(0, 1, 0, 1));
}
else
{
if (yData[i - 1] >= yData[i]) { //Gone down
ImPlot::PushStyleColor(ImPlotCol_Line, ImVec4(1, 0, 0, 1));
ImPlot::PushStyleColor(ImPlotCol_Fill, ImVec4(1, 0, 0, 1));
}
else //Gone up
{
ImPlot::PushStyleColor(ImPlotCol_Line, ImVec4(0, 1, 0, 1));
ImPlot::PushStyleColor(ImPlotCol_Fill, ImVec4(0, 1, 0, 1));
}
}
ImPlot::PlotBars("Bar Graph##Line Individual", &xData[i], &yData[i], 1, 86400 * 0.25f);
ImPlot::PopStyleColor();
ImPlot::PopStyleColor();
}
ImPlot::EndPlot();
}
ImGui::End();
//Fps checker
sprintf_s(fps, "%.3f", ImGui::GetIO().Framerate);
glfwSetWindowTitle(window, fps);
// Rendering
ImGui::Render();
glfwGetFramebufferSize(window, &windowWidth, &windowHeight);
glViewport(0, 0, windowWidth, windowHeight);
glClearColor(0.45f, 0.55f, 0.60f, 1.00f);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window);
}
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImPlot::DestroyContext();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
The bottom bar graph is supposed to represent something else, however the example still demonstrates the issue. Click the button "LoadData" and then you'll see. But in my actual data, despite the bar graph representing completely different data (not relevant to above data), it still has this same issue.
@epezent Hi, I am just wondering if you have seen this thread, since it has been a few months :)
I had started to investigate. Was able to reproduce your issue, but never dug into the root cause. I don't know when I will be able to. If you decide to investigate on your own, feel free to submit a PR or ask for feedback.