implot icon indicating copy to clipboard operation
implot copied to clipboard

Auto resize with linked axis

Open peterwilson136 opened this issue 5 years ago • 4 comments

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.

peterwilson136 avatar Mar 29 '21 06:03 peterwilson136

Can you recreate the issue with dummy data in a minimal working example I can compile and test?

epezent avatar Mar 31 '21 14:03 epezent

#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.

peterwilson136 avatar Apr 01 '21 21:04 peterwilson136

@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.

epezent avatar Jun 02 '21 23:06 epezent