Source code for gempy_viewer.API._plot_2d_API

from typing import Union, List, Optional

import numpy as np
import matplotlib.pyplot as plt

from gempy.core.data import GeoModel
from gempy.core.data.grid_modules import RegularGrid
from gempy_viewer.API._plot_2d_sections_api import plot_sections
from gempy_viewer.core.data_to_show import DataToShow
from gempy_viewer.core.section_data_2d import SectionData2D
from gempy_viewer.modules.plot_2d.multi_axis_manager import sections_iterator, orthogonal_sections_iterator
from gempy_viewer.modules.plot_2d.visualization_2d import Plot2D


[docs] def plot_2d(model: GeoModel, n_axis=None, section_names: list = None, cell_number: Optional[Union[int | list[int] | str | list[str]]] = None, direction: Optional[Union[str | list[str]]] = 'y', series_n: Union[int, List[int]] = 0, legend: bool = True, ve=1, block=None, override_regular_grid=None, kwargs_topography=None, kwargs_lithology=None, kwargs_scalar_field=None, **kwargs): """Plot 2-D sections of geomodel. Plot cross sections either based on custom section traces or cell number in xyz direction. Options to plot lithology block, scalar field or rendered surface lines. Input data and topography can be included. Args: show_block (bool): If True and model has been computed, plot cross section of the final model. show_values (bool): If True and model has been computed, plot cross section of the value... TODO need to add attribute to choose which value to be plot model: Geomodel object with solutions. n_axis (int): Subplot axis for multiple sections section_names (list): Names of predefined custom section traces cell_number (list): Position of the array to plot direction (str): Cartesian direction to be plotted (xyz) series_n (int): number of the scalar field. ve (float): vertical exageration override_regular_grid (numpy.ndarray): Numpy array of the size of model.grid.regular_grid. If provided, the regular grid will be overriden by this array. kwargs_topography (dict): * fill_contour * hillshade (bool): Calculate and add hillshading using elevation data * azdeg (float): azimuth of sun for hillshade * altdeg (float): altitude in degrees of sun for hillshade Keyword Args: legend (bool): If True plot legend. Default True show (bool): Call matplotlib show show_data (bool): Show original input data. Defaults to True. show_results (bool): If False, override show lith, show_calar, show_values show_lith (bool): Show lithological block volumes. Defaults to True. show_scalar (bool): Show scalar field isolines. Defaults to False. show_boundaries (bool): Show surface boundaries as lines. Defaults to True. show_topography (bool): Show topography on plot. Defaults to False. (Note Sep 2023) If True this is showing the height map instead of the geological map. Returns: :class:`gempy.plot.visualization_2d.Plot2D`: Plot2D object """ if kwargs_lithology is None: kwargs_lithology = dict() if kwargs_topography is None: kwargs_topography = dict() if kwargs_scalar_field is None: kwargs_scalar_field = dict() if section_names is None and cell_number is None and direction is not None: cell_number = ['mid'] show = kwargs.get('show', True) if block is not None: import warnings regular_grid = block warnings.warn('block is going to be deprecated. Use regular grid instead', DeprecationWarning) section_names = [] if section_names is None else section_names section_names = np.atleast_1d(section_names) if cell_number is None: cell_number = [] elif cell_number == 'mid': cell_number = ['mid'] direction = [] if direction is None else direction if type(cell_number) != list: cell_number = [cell_number] if type(direction) != list: direction = [direction] * len(cell_number) if n_axis is None: n_axis = len(section_names) + len(cell_number) if type(series_n) is int: series_n = [series_n] * n_axis # * Grab from kwargs all the show arguments and create the proper class. This is for backwards compatibility can_show_results = model.solutions is not None data_to_show = DataToShow( n_axis=n_axis, show_data=kwargs.get('show_data', True), _show_results=kwargs.get('show_results', can_show_results), show_surfaces=kwargs.get('show_surfaces', True), show_lith=kwargs.get('show_lith', True), show_scalar=kwargs.get('show_scalar', False), show_boundaries=kwargs.get('show_boundaries', True), show_topography=kwargs.get('show_topography', False), show_section_traces=kwargs.get('show_section_traces', True), show_values=kwargs.get('show_values', False), show_block=kwargs.get('show_block', False) ) # is 10 and 10 because in the ax pos is the second digit n_columns_ = 1 if len(section_names) + len(cell_number) < 2 else 2 n_columns = n_columns_ * 10 # This is for the axis location syntax n_rows = (len(section_names) + len(cell_number)) / n_columns_ n_columns_ = np.max([n_columns_, 1]) n_rows = np.max([n_rows, 1]) p = Plot2D() p.create_figure(cols=n_columns_, rows=n_rows, **kwargs) # * This creates fig and axes section_data_list: list[SectionData2D] = sections_iterator( plot_2d=p, gempy_model=model, sections_names=section_names, n_axis=n_axis, n_columns=n_columns, ve=ve, projection_distance=kwargs.get('projection_distance', 0.2 * model.transform.isometric_scale) ) orthogonal_section_data_list: list[SectionData2D] = orthogonal_sections_iterator( initial_axis=len(section_data_list), plot_2d=p, gempy_model=model, direction=direction, cell_number=cell_number, n_axis=n_axis, n_columns=n_columns, ve=ve, projection_distance=kwargs.get('projection_distance', 0.2 * model.transform.isometric_scale) ) section_data_list.extend(orthogonal_section_data_list) p.section_data_list = section_data_list plot_sections( gempy_model=model, sections_data=section_data_list, data_to_show=data_to_show, ve=ve, series_n=series_n, override_regular_grid=override_regular_grid, legend=legend, kwargs_topography=kwargs_topography, kwargs_scalar_field=kwargs_scalar_field, kwargs_lithology=kwargs_lithology ) if show is True: p.fig.show() return p
def plot_section_traces(model: GeoModel, section_names: list[str] = None): """ Plot section traces of section grid in 2-D topview (xy). """ from gempy_viewer.modules.plot_2d.drawer_traces_2d import plot_section_traces as pst plot: Plot2D = plot_2d( model=model, n_axis=1, direction=['z'], cell_number=[-1], show_data=False, show_boundaries=False, show_lith=False, show=False ) pst( gempy_model=model, ax=plot.axes[0], section_names=section_names ) plot.fig.show() return pst def plot_topology(regular_grid: RegularGrid, edges, centroids, direction="y", ax=None, scale=True, label_kwargs=None, edge_kwargs=None): """Plot the topology adjacency graph in 2-D. Args: geo_model ([type]): GemPy geomodel instance. edges (Set[Tuple[int, int]]): Set of topology edges. centroids (Dict[int, Array[int, 3]]): Dictionary of topology id's and their centroids. direction (Union["x", "y", "z", optional): Section direction. Defaults to "y". label_kwargs (dict, optional): Keyword arguments for topology labels. Defaults to None. edge_kwargs (dict, optional): Keyword arguments for topology edges. Defaults to None. """ if ax is None: fig, ax = plt.subplots(figsize=(10, 10)) res = regular_grid.resolution if direction == "y": c1, c2 = (0, 2) e1 = regular_grid.extent[1] - regular_grid.extent[0] e2 = regular_grid.extent[5] - regular_grid.extent[4] d1 = regular_grid.extent[0] d2 = regular_grid.extent[4] # ? (miguel, Oct 23) When is this condition used? if len(list(centroids.items())[0][1]) == 2: c1, c2 = (0, 1) r1 = res[0] r2 = res[2] elif direction == "x": c1, c2 = (1, 2) e1 = regular_grid.extent[3] - regular_grid.extent[2] e2 = regular_grid.extent[5] - regular_grid.extent[4] d1 = regular_grid.extent[2] d2 = regular_grid.extent[4] r1 = res[1] r2 = res[2] elif direction == "z": c1, c2 = (0, 1) e1 = regular_grid.extent[1] - regular_grid.extent[0] e2 = regular_grid.extent[3] - regular_grid.extent[2] d1 = regular_grid.extent[0] d2 = regular_grid.extent[2] r1 = res[0] r2 = res[1] tkw = { "color" : "white", "fontsize" : 13, "ha" : "center", "va" : "center", "weight" : "ultralight", "family" : "monospace", "verticalalignment" : "center", "horizontalalignment": "center", "bbox" : dict(boxstyle='round', facecolor='black', alpha=1), } if label_kwargs is not None: tkw.update(label_kwargs) lkw = { "linewidth": 1, "color" : "black" } if edge_kwargs is not None: lkw.update(edge_kwargs) for a, b in edges: # plot edges x = np.array([centroids[a][c1], centroids[b][c1]]) y = np.array([centroids[a][c2], centroids[b][c2]]) if scale: x = x * e1 / r1 + d1 y = y * e2 / r2 + d2 ax.plot(x, y, **lkw) for node in np.unique(list(edges)): x = centroids[node][c1] y = centroids[node][c2] if scale: x = x * e1 / r1 + d1 y = y * e2 / r2 + d2 ax.text(x, y, str(node), **tkw) plt.show()