Isaiahensley / Aquatic-RIG

Our Senior Capstone project focuses on developing a Streamlit website dedicated to the visualization of aquatic NetCDF datasets. Aquatic data is inherently complex, being both spatiotemporal—capturing information over different times and space. Our website will let users alternate through time and depth to give comprehensive visuals for their data.
https://aquaticrig-develop.streamlit.app/
0 stars 1 forks source link

Creating Quiver Plot Visualization #62

Closed Isaiahensley closed 6 months ago

Isaiahensley commented 6 months ago

Description: This issue is focused on creating a Quiver Plot option on the Dataset Management page. This visualization option will be similar to the Heat Map option that was completed. This will allow users to visualize water currents in an aquatic source.

Expected vs. Actual Behavior: Users should be able to select "Quiver plot" as a Visualization option and be prompted to select the: U - water current velocity on the Zonal axis (left to right) V - water current velocity on the Meridional axis (up to down) These values should change depending on the time and depth dimension that is selected. This should update in real-time when a different dimension is selected.

Screenshot Example: image

Objective: Creating User-friendly Quiverplot for water current plot.

Isaiahensley commented 6 months ago

Description:

Completed the Quiver Plot visualization option.


Steps to reproduce:

1) Go to the Dataset Management page image 2) Upload .nc file(s) image 3) Select Quiver Plot as the Visualization Option image 4) Choose the x-velocity and y-velocity (in most cases this will be "u" and "v") image 5) A Quiver Plot is generated and the Time and Depth can be adjusted. image


Quiver Plot GIF:

gif


Code Snippet:

def quiverplot(variables_not_dimensions, file_content, datetime_str, depth, selected_xvelocity, selected_yvelocity):
    # Load the NetCDF file from BytesIO object
    nc_file = nc.Dataset('in-memory', memory=file_content)

    try:
        # Convert the selected datetime string back to a datetime object
        selected_datetime = parse_datetime(datetime_str)

        # Find the index of the selected time
        time_var = nc_file.variables['time']
        time_units = time_var.units
        selected_time_index = np.where(nc.num2date(time_var[:], units=time_units) == selected_datetime)[0][0]

        # Access the data for the selected u and v velocity variables
        u_data = nc_file.variables[selected_xvelocity][selected_time_index, depth, :, :]
        v_data = nc_file.variables[selected_yvelocity][selected_time_index, depth, :, :]

        # Ensure lat and lon are 2D arrays for quiver plotting
        lat = nc_file.variables['lat'][:]
        lon = nc_file.variables['lon'][:]
        Lon, Lat = np.meshgrid(lon, lat)

        # Optionally, reduce the density of arrows for clarity
        skip = (slice(None, None, 5), slice(None, None, 5))  # Adjust the slicing for desired arrow density
        u_data = u_data[skip]
        v_data = v_data[skip]
        Lon = Lon[skip]
        Lat = Lat[skip]

        # Setting up the plot with a dark background for white elements to stand out
        plt.style.use('dark_background')
        fig, ax = plt.subplots(figsize=(10, 6))
        q = ax.quiver(Lon, Lat, u_data, v_data, color='white')  # Set arrow color to white

        # Include a key to indicate scale, with text in white
        ax.quiverkey(q, X=0.9, Y=1.05, U=10, label='10 units', labelpos='E', color='white')

        # Set axis labels and title with white text
        ax.set_xlabel('Longitude', color='white')
        ax.set_ylabel('Latitude', color='white')
        #ax.set_title(f'Quiver plot for {selected_xvelocity} and {selected_yvelocity} at depth {depth} on {datetime_str}', color='white')

        # Changing tick parameters to white
        ax.tick_params(axis='both', colors='white')

        fig.tight_layout()

        buf = BytesIO()
        fig.savefig(buf, format="png", dpi=300, transparent=True)
        #st.image(buf, use_column_width=True)
        st.image(buf, width=1080)
    except Exception as e:
        st.error(f"Error generating quiver plot: {e}")
    finally:
        nc_file.close()