From f684019447f9ced70a7ca5033e0772d60ebff7ea Mon Sep 17 00:00:00 2001
From: Duncan Holmes <dholmes4@huskers.unl.edu>
Date: Sat, 12 Apr 2025 20:05:06 -0500
Subject: [PATCH] still need to add print statments if you want to know all of
 what's going on but i'd rather like... not do that so i'm not going to

---
 example_graph_code.py | 166 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 157 insertions(+), 9 deletions(-)

diff --git a/example_graph_code.py b/example_graph_code.py
index c01d003..f086f47 100644
--- a/example_graph_code.py
+++ b/example_graph_code.py
@@ -6,6 +6,7 @@ from kivy.lang import Builder
 
 import matplotlib.pyplot as plt
 from matplotlib.backends.backend_agg import FigureCanvasAgg
+import matplotlib.dates as mdates  # Import for date formatting
 
 import pandas as pd
 from io import BytesIO
@@ -15,50 +16,197 @@ from PIL import Image as PILImage
 class GraphScreen(Screen):
 
     def __init__(self, **kwargs):
+        print(f"\t\t i'm in the constructor now")
+        print(f"\t\t i'm gonna call Screen's contructor because that's how it is....")
         super().__init__(**kwargs)
+        print(f"\t\t now i'm gonna set graph_texture, which is a variable, to None. Don't worry—it gets set later.")
         self.graph_texture = None
+        print(f"\t\t that's the end of the constructor hehe")
+        print('\n\n')
 
     def on_enter(self):
-        # Sample CoinGecko-style data
-        data = {
-            "prices": [
+        print(f"\t\t\t we're in on_enter now .  i think this is a 'callback function that gets called when the screen is entered'")
+        print(f"\t\t\t ok well if you say so mr. autocomplete line bot :- / \n")
+
+        # Sample CoinGecko style data
+        data = \
+        {
+            "prices":
+            [
                 [1711843200000, 69702.31],
                 [1711929600000, 71246.95],
                 [1711983682000, 68887.75]
             ]
         }
+        print(f"\t\t\t data: {data}")
 
+        # Create DataFrame
+        """
+        this is screwy 
+        DataFrame object
+            use the parameter collums & the strings... as the labels for said collums
+            use the data dictionary's prices's values as a parameter for inputs into a table
+            
+            the visualized version of this is 
+            timestamp           price
+            1711843200000       69702.31
+            1711929600000       71246.95
+            1711983682000       68887.75
+            
+        """
         df = pd.DataFrame(data["prices"], columns=["timestamp", "price"])
+        print(f"\t\t\t df: {df}")
+
+        print(f"\t\t\t converting timestamp to datetime...")
+
+        """
+        ok now that we have that weird ahh python table object working
+        let's convert the numerical bull-pucky timestamps to datetime objects
+        from 
+        ##### number number blah blah ERRUUGHGHGHH -------> yyyy/mm/dd/hh/mm/ss
+        
+        the way it does this is weird but cool
+        1. call the values inside the timestamp collum like a dicationry does
+        2. set those values .... by using pd which is like a dictionary? i doubt it.
+            use pd which is a lower level function in this context ... and it's method
+            which converts the values of "timestamp" into datetime objects
+            WHICH IS BADASS
+        3. the unit="ms" is used becuase the CoinGecko goes down to the milasecond 
+        """
+        # convert timestamp to datetime
         df["timestamp"] = pd.to_datetime(df["timestamp"], unit="ms")
+        print(f"\t\t\t df: {df}")
 
-        # Plot
+        """
+        big boy method useage 
+        
+        fig .... a figure object 'should be seen as the entire graph'
+            apperntly you can save it as a png or jpeg
+                fig.savefig("my_plot.png")
+            or 'use it in kivy like you're doing right now'
+            
+        ax ... axes
+            ax stand for axes 
+            ax.plot(x, y)   ?????
+            "this is the actual area where you graph is drawn"
+            like the little commie block the graph actually lives in 
+            
+            ax.plot(x, y)         # Plot lines
+            ax.set_title(...)     # Add a title
+            ax.set_xlabel(...)    # X-axis label
+            ax.set_ylabel(...)    # Y-axis label
+            ax.legend(...)        # Add a legend
+            
+        plt is a static object that allows for static method calling. i guess
+        .subplots() returns a figure and an axis object : - ) 
+        """
+        # Create Matplotlib Figure and Axis
         fig, ax = plt.subplots()
+        print(f'\t\t\t ax: {ax}')
+        print(f'\t\t\t fig: {fig}')
+
+        """
+        ax.plot(x, y)         # Plot lines
+        ax.set_title(...)     # Add a title
+        ax.set_xlabel(...)    # X-axis label
+        ax.set_ylabel(...)    # Y-axis label
+        ax.legend(...)        # Add a legend
+        """
+        print(f"\t\t\t whole lotta ax methods i'm boutta call")
+        # Plot the data
         ax.plot(df["timestamp"], df["price"], label="Price", color="green")
+        print(f"\t\t\tgave ax plot points. like (x,y) but with dates & prices instead of numbers")
+
         ax.set_title("Price Over Time")
+        print("\t\t\tgave ax a title")
+
         ax.set_xlabel("Date")
+        print("\t\t\tgave ax a label for it's x axis")
+
         ax.set_ylabel("Price (USD)")
+        print("\t\t\tgave ax a label for it's y axis")
+
         ax.legend()
+        print("\t\t\tgave ax a legend. that means the axis-es are labeled")
+
+        print(f'\t\t\t ax: {ax}')
+
+        # **Key Change:**
+        # Manually set the x-axis tick positions to the exact datetime values in the DataFrame.
+        #       it's a method. don't got nothin else to tell ye
+        print(f"\t\t\t i'm gonna make sure only the dates put in the data, show up on the graph ok?")
+        ax.set_xticks(df["timestamp"])
+        print(f"\t\t\t ax.get_xticks = {ax.get_xticks()}")
+
+        # Format the ticks to display in "YYYY-MM-DD" format.
+        print(f"\t\t\t i'm gonna format the numeric gobbelty gook that is the timestamps into a better yyyy_mm_dd format")
+        ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
+        print(f"\t\t\t ax.xaxis.get_major_formatter() = {ax.xaxis.get_major_formatter()}")
 
-        # Convert plot to Kivy texture
+        # Note: Using manual ticks makes auto-formatting less necessary.
+        # fig.autofmt_xdate()  # This line is optional now. BECAUSE IT AUTO FORMATS. I'M KEEPING IT IN JUST IN CASE.... world explodes idk
+
+        """
+        1. makes a FigureCanvasAgg object using fig... a figure object only
+            wow 
+        2. canvas.draw = .... draws the figure onto the canvas
+                uhhh ok thanks autocomplete
+        3. buf = BytesIO() = ... creates a buffer object
+                ?
+        4. fig.savefig(buf, format='png') = ... saves the figure to the buffer object
+        5. buf.seek(0) = ... seeks the buffer object to the beginning
+        """
+        # Convert the plot to a Kivy texture
         canvas = FigureCanvasAgg(fig)
         canvas.draw()
         buf = BytesIO()
         fig.savefig(buf, format='png')
         buf.seek(0)
 
+        """
+        1. pil_image = PILImage.open(buf) = ... opens the buffer object as an image
+        2. pil_image = pil_image.transpose(PILImage.FLIP_TOP_BOTTOM) = ... flips the image vertically
+            i guess it comes not vertically out the gate? why? 
+            if you change FLIP_TOP_BOTTOM to FLIP_LEFT_RIGHT it flips it horizontally
+            and if you change FLIP_TOP_BOTTOM to DEFAULT_STRATEGY it assumely keeps it as it is orginally 
+            so that's why the orginal command is there 
+        3. tex = Texture.create(size=pil_image.size, colorfmt='rgba') = ... creates a texture object
+            a texture object is a kivy image widget's property
+            so like
+            
+            Image:
+                id: image_id
+                texture: tex
+        """
+        # Flip the image vertically to correct the orientation for Kivy
         pil_image = PILImage.open(buf).transpose(PILImage.FLIP_TOP_BOTTOM)
         tex = Texture.create(size=pil_image.size, colorfmt='rgba')
         tex.blit_buffer(pil_image.convert('RGBA').tobytes(), colorfmt='rgba', bufferfmt='ubyte')
-        tex.flip_vertical()
 
-        # Access the image widget via ids correctly
+        #if you had this your graph would be flipped veritcally
+        #the.... uhm. the birdy that told me to how to write this code put this here and it made the graph look funny
+        #i commented it out. and it worked.
+        #i found that very funny.
+        #tex.flip_vertical()
+
+        # Save the generated texture
         self.graph_texture = tex
 
 
 class MyApp(App):
     def build(self):
-        return Builder.load_file('example_graph_code.kv')
+        print("\t i'm pretty sure this is MyApp's run function")
+        print("\t i'm gonna use Builder's static method load_file() to load your file...")
+        kivy_file_directory = 'example_graph_code.kv'
+        print(f"\t {kivy_file_directory}")
+        return Builder.load_file(kivy_file_directory)
+        print(f"\t i'm done with the build function ;- )")
+
 
 if __name__ == "__main__":
+    print('you pressed the start button :-) ')
+    print("i'm making a MyApp object called app")
     app = MyApp()
-    app.run()
\ No newline at end of file
+    print("i'm making app do the run function")
+    app.run()
+    print("program's done :-(")
-- 
GitLab