# Plotting heatmaps When running a set of KMC simulations at various operating conditions, 2D heatmaps can be created using various specialized `plot_X` functions such as `plot_tof` or `plot_selectivity`. ### Parameters #### Mandatory parameters for all plot types - **`ax`** (`matplotlib.axes.Axes`): Axis object where the contour plot should be created. - **`scan_path`** (`str`): Path of the directory containing all the scan jobs. - **`x`** (`str`): Magnitude to plot on the x-axis. Possible values: - `'pressure_X'`, where `X` is a gas species. - `'temperature'`. - `'total_pressure'`. - **`y`** (`str`): Magnitude to plot on the y-axis. Possible values: - `'pressure_Y'`, where `Y` is a gas species. - `'temperature'`. - `'total_pressure'`. Depending on the type of plot, some additional parameters might be needed (see below). #### Optional parameters - **`cmap`** (`str`): Colormap used to map scalar data to colors. Accepts colormap instances or registered names. **Default**: depends on the function. - **`show_points`** (`bool`): Displays grid points as black dots if `True`. **Default**: `False`. - **`show_colorbar`** (`bool`): Displays the colorbar if `True`. **Default**: `True`. - **`auto_title`** (`bool`): Automatically generates titles for subplots if `True`. **Default**: `False`. ### Heatmap types #### TOF (Turnover Frequency) Plot the TOF (in molec·s⁻¹·Å⁻²) of a given gas-phase species. **Additional parameters:** Mandatory: - **`gas_spec`** (`str`): Name of the gas-phase species for the TOF difference calculation. Optional: - **`min_molec`** (`int`): Minimum total production in both main and reference simulations to consider the result valid. **Default**: `1`. - **`weights`** (`str`): Weights for the averages. Possible values: - `'time'` - `'events'` - `None` (all weights are set to 1) **Default**: `None`. - **`levels`** (`list` or `np.ndarray`): Contour levels to use in the plot. When provided, TOF values are clipped to the minimum and maximum values in this list. - **`analysis_range`** (`list`): Portion of the simulation data to analyze. **Default**: `[0, 100]`. - **`range_type`** (`str`): The type of window to apply. Possible values: - `'time'` (based on simulated time) - `'nevents'` (based on the number of events) **Default**: `'time'`. - **`show_max`** (`bool`): Display a golden `'*'` marker at the point with the highest TOF. **Default**: `False`. **Example:** ```python import numpy as np import matplotlib.pyplot as plt from zacrostools.plot_functions.tof import plot_tof fig, axs = plt.subplots(1, figsize=(4.3, 3.5)) plot_tof( ax=axs, scan_path='simulation_results', x='pressure_CH4', y='pressure_CO2', gas_spec='H2', # Changed default is now 1, but we can override as needed: min_molec=0, # analysis_range is used to specify which portion of the simulation to analyze: analysis_range=[50, 100], range_type='time', # If levels are not provided, the function auto-scales the TOF data: levels=np.logspace(-1, 4, num=11), auto_title=True, show_points=False, show_colorbar=True ) plt.tight_layout() plt.savefig('tof_heatmap.png', dpi=300, bbox_inches='tight', transparent=False) plt.show() ```
TOF heatmap
#### ∆TOF (Delta TOF) Plot the difference in Turnover Frequencies (TOF) between a main simulation and a reference simulation for a specified gas-phase species. The difference can be either *absolute* (`main - reference`) or *relative*. **Additional parameters:** Mandatory: - **`gas_spec`** (`str`): Name of the gas-phase species for the TOF difference calculation. - **`scan_path_ref`** (`str`): Path to the reference simulation directories. Optional: - **`difference_type`** (`str`): Type of TOF difference to compute. Must be either `'absolute'` or `'relative'`. **Default**: `'absolute'`. - **`scale`** (`str`): Determines the color scaling of the difference. Possible values: - `'log'` - `'lin'` **Default**: `'log'`. - **`min_molec`** (`int`): Minimum total production in both main and reference simulations to consider the result valid. **Default**: `1`. - **`max_dtof`** (`float`): Maximum absolute value for \(\Delta\)TOF. For relative differences, the default is 100. If provided, values above (or below the negative) limit are clipped. - **`min_dtof`** (`float`): Threshold that defines the smallest nonzero \(\Delta\)TOF to display. By default, it’s set automatically (depending on `max_dtof`). - **`nlevels`** (`int`): Number of discrete boundaries if you want to segment the \(\Delta\)TOF scale. - `0`: use continuous normalization. - Must be a positive odd integer (`>=3`) for discrete normalization. **Default**: `0`. - **`weights`** (`str`): Weights for the averages. Possible values: - `'time'` - `'events'` - `None` (all weights are set to 1) **Default**: `None`. - **`analysis_range`** (`list`): Portion of the simulation data to analyze. **Default**: `[0, 100]`. - **`range_type`** (`str`): The type of window to apply. Possible values: - `'time'` - `'nevents'` **Default**: `'time'`. **Example:** ```python import matplotlib.pyplot as plt from zacrostools.plot_functions.dtof import plot_dtof fig, ax = plt.subplots(1, figsize=(4.3, 3.5)) plot_dtof( ax=ax, scan_path='simulation_results', scan_path_ref='reference_results', x='pressure_CH4', y='pressure_CO2', gas_spec='H2', difference_type='absolute', scale='log', min_molec=0, nlevels=11, analysis_range=[50, 100], range_type='time', auto_title=True, show_points=False, show_colorbar=True ) plt.tight_layout() plt.savefig('dtof_heatmap.png', dpi=300, bbox_inches='tight', transparent=False) plt.show() ```
∆TOF heatmap
#### Selectivity (%) Plot the selectivity (in %) of a **main product** with respect to one or more **side products**. **Additional parameters:** Mandatory: - **`main_product`** (`str`): Name of the main product for the selectivity calculation. - **`side_products`** (`list`): List of side products for the selectivity calculation. Optional: - **`min_molec`** (`int`): Minimum combined production (main + side products) required for a valid selectivity value. **Default**: `1`. - **`weights`** (`str`): Weights for the averages. Possible values: - `'time'` - `'events'` - `None` (all weights are set to 1) **Default**: `None`. - **`levels`** (`list` or `np.ndarray`): Contour levels to use in the plot (e.g., `np.linspace(0, 100, 11, dtype=int)`). If provided, selectivity values are clipped to the minimum and maximum values in this list. **Default**: `np.linspace(0, 100, 11, dtype=int)`. - **`analysis_range`** (`list`): Portion of the simulation data to analyze. **Default**: `[0, 100]`. - **`range_type`** (`str`): The type of window to apply. Possible values: - `'time'` - `'nevents'` **Default**: `'time'`. - **`cmap`** (`str`): Colormap used to map scalar data to colors. **Default**: `'Greens'`. **Example:** ```python import numpy as np import matplotlib.pyplot as plt from zacrostools.plot_functions.selectivity import plot_selectivity fig, ax = plt.subplots(1, figsize=(4.3, 3.5)) plot_selectivity( ax=ax, scan_path='simulation_results', x='pressure_CH4', y='pressure_CO2', main_product='H2', side_products=['H2O'], min_molec=100, analysis_range=[50, 100], range_type='time', auto_title=True, show_points=False, show_colorbar=True ) plt.tight_layout() plt.savefig('selectivity_heatmap.png', dpi=300, bbox_inches='tight', transparent=False) plt.show() ```
Selectivity heatmap
#### Coverage (%) Plot the coverage (in %) of specified surface species (or total coverage) on a given site type. **Additional parameters:** Mandatory: - **`surf_spec`** (`str` or `list`): Surface species to include in the coverage calculation. - `'all'`: Total coverage (of all adsorbates) is shown. - A single species name (`'CO*'`) or a list of species (`['CH*', 'C*']`) can also be provided. Optional: - **`site_type`** (`str`): The site type on which coverage is computed. **Default**: `'default'`. - **`weights`** (`str`): Weights for the averages. Possible values: - `'time'` - `'events'` - `None` (all weights are set to 1) **Default**: `None`. - **`levels`** (`list` or `np.ndarray`): Contour levels to use in the plot (e.g., `np.linspace(0, 100, 11, dtype=int)`). If provided, coverage values are clipped to the minimum and maximum values in this list. **Default**: `np.linspace(0, 100, 11, dtype=int)`. - **`analysis_range`** (`list`): Portion of the simulation data to analyze. **Default**: `[0, 100]`. - **`range_type`** (`str`): The type of window to apply. Possible values: - `'time'` - `'nevents'` **Default**: `'time'`. - **`cmap`** (`str`): Colormap used to map scalar data to colors. **Default**: `'Oranges'`. **Example:** ```python import numpy as np import matplotlib.pyplot as plt from zacrostools.plot_functions.coverage import plot_coverage fig, ax = plt.subplots(1, figsize=(4.3, 3.5)) plot_coverage( ax=ax, scan_path='simulation_results', x='pressure_CH4', y='pressure_CO2', surf_spec='all', site_type='tC', weights='time', analysis_range=[50, 100], range_type='time', auto_title=True, show_points=False, show_colorbar=True ) plt.tight_layout() plt.savefig('coverage_heatmap.png', dpi=300, bbox_inches='tight', transparent=False) plt.show() ```
Coverage heatmap
#### Phase Diagram Plot a phase diagram where each point is assigned a **dominant surface species** (or `NaN` if coverage is too low). The color encodes these dominant species, grouped according to user-provided or auto-generated labels. **Additional parameters:** *(No additional mandatory parameters are required.)* Optional: - **`site_type`** (`str`): Site type to consider when retrieving the dominant surface species. **Default**: `'default'`. - **`min_coverage`** (`float` or `int`): Minimum coverage threshold (%) for a species to be considered dominant. **Default**: `50.0`. - **`tick_labels`** (`dict`): Custom mapping for species grouping and colorbar labels. The keys are used as colorbar labels (e.g., `'$CH_{x}$'`), and the values are lists of species names (e.g., `['CH3', 'CH2', 'C']`). When not provided, the function automatically parses a `simulation_input.dat` file from the first simulation directory to assign each species to its own group. - **`weights`** (`str`): Weights for the averages. Possible values: - `'time'` - `'events'` - `None` (all weights are set to 1) **Default**: `None`. - **`analysis_range`** (`list`): Portion of the simulation data to analyze. **Default**: `[0, 100]`. - **`range_type`** (`str`): The type of window to apply. Possible values: - `'time'` - `'nevents'` **Default**: `'time'`. **Example:** ```python import matplotlib.pyplot as plt from zacrostools.plot_functions.phasediagram import plot_phasediagram tick_labels = { '$CH_{x}$': ['CH3', 'CH3_Pt', 'CH2', 'CH2_Pt', 'CH', 'CH_Pt', 'C', 'C_Pt'], '$CHO/COH$': ['CHO', 'CHO_Pt', 'COH', 'COH_Pt'], '$CO$': ['CO', 'CO_Pt'], '$COOH$': ['COOH', 'COOH_Pt'], '$CO_{2}$': ['CO2', 'CO2_Pt'], '$H$': ['H', 'H_Pt'], '$H_{2}O$': ['H2O', 'H2O_Pt'], '$OH$': ['OH', 'OH_Pt'], '$O$': ['O', 'O_Pt'] } fig, ax = plt.subplots(1, figsize=(4.3, 3.5)) plot_phasediagram( ax=ax, scan_path='simulation_results', x='pressure_CO2', y='pressure_CH4', site_type='tC', min_coverage=50.0, tick_labels=tick_labels, weights='time', analysis_range=[50, 100], range_type='time', auto_title=True, show_points=False, show_colorbar=True ) plt.tight_layout() plt.savefig('phase_diagram.png', dpi=300, bbox_inches='tight', transparent=False) plt.show() ```
Phase diagram heatmap
#### Final Time (s) Plot the **final simulation time** (in seconds) for each job in a 2D heatmap. The color scale is logarithmically normalized. **Additional parameters:** *(No additional mandatory parameters are required.)* Optional: - **`levels`** (`list` or `np.ndarray`): Contour levels for the plot. If provided, final time values are clipped to the minimum and maximum in this list. **Default**: `None`. **Example:** ```python import numpy as np import matplotlib.pyplot as plt from zacrostools.plot_functions.finaltime import plot_finaltime fig, ax = plt.subplots(1, figsize=(4.3, 3.5)) plot_finaltime( ax=ax, scan_path='simulation_results', x='pressure_CH4', y='pressure_CO2', levels=np.logspace(-5, 7, num=13), show_points=False, show_colorbar=True, auto_title=True ) plt.tight_layout() plt.savefig('finaltime_heatmap.png', dpi=300, bbox_inches='tight', transparent=False) plt.show() ```
Final time heatmap
#### Energy Slope Plot the **energy slope** computed during the KMC simulation in a 2D heatmap. By default, data are shown on a logarithmic scale (using `LogNorm`). **Additional parameters:** *(No additional mandatory parameters are required.)* Optional: - **`levels`** (`list` or `np.ndarray`): Levels for normalization. If provided, the color scale is clipped between `min(levels)` and `max(levels)`. **Default**: `np.logspace(-11, -8, num=7)`. - **`analysis_range`** (`list`): Portion of the simulation data to analyze. **Default**: `[0, 100]`. - **`range_type`** (`str`): The dimension considered in the analysis. Possible values: - `'time'` - `'nevents'` **Default**: `'time'`. **Example:** ```python import matplotlib.pyplot as plt import numpy as np from zacrostools.plot_functions.energyslope import plot_energyslope fig, ax = plt.subplots(1, figsize=(4.3, 3.5)) plot_energyslope( ax=ax, scan_path='simulation_results', x='pressure_CH4', y='pressure_CO2', analysis_range=[50, 100], range_type='time', auto_title=True, show_points=False, show_colorbar=True ) plt.tight_layout() plt.savefig('energyslope_heatmap.png', dpi=300, bbox_inches='tight', transparent=False) plt.show() ```
Energy slope heatmap
#### Issues Check each simulation for **issues** and visualize the results in a yes/no heatmap. **Additional parameters:** Mandatory: - **`analysis_range`** (`list`): Portion of the simulation data to analyze (e.g., `[0, 100]`). If `None`, it is internally set to `[0, 100]`. Optional: - **`range_type`** (`str`): The dimension used for slicing the simulation data. Possible values: - `'time'` - `'nevents'` **Default**: `'time'`. - **`cmap`** (`str`): Colormap used for plotting. **Default**: `'RdYlGn'`. - **`verbose`** (`bool`): If `True`, prints the paths of simulations that contain issues. **Default**: `False`. **Example:** ```python import matplotlib.pyplot as plt from zacrostools.plot_functions.issues import plot_issues fig, ax = plt.subplots(1, figsize=(4.3, 3.5)) plot_issues( ax=ax, scan_path='simulation_results', x='pressure_CH4', y='pressure_CO2', analysis_range=[50, 100], range_type='time', verbose=True, auto_title=True, show_colorbar=True, show_points=False ) plt.tight_layout() plt.savefig('issues_heatmap.png', dpi=300, bbox_inches='tight', transparent=False) plt.show() ```
Issues heatmap
### Figure with multiple heatmaps Different specialized plotting functions can be combined in a single figure, as illustrated below. Each function (`plot_tof`, `plot_coverage`, `plot_phasediagram`, `plot_selectivity`, `plot_finaltime`, etc.) handles a particular type of heatmap. ```python import numpy as np import matplotlib.pyplot as plt # Import the specialized plotting functions from zacrostools.plot_functions.tof import plot_tof from zacrostools.plot_functions.coverage import plot_coverage from zacrostools.plot_functions.phasediagram import plot_phasediagram from zacrostools.plot_functions.selectivity import plot_selectivity from zacrostools.plot_functions.finaltime import plot_finaltime # General parameters scan_path = 'simulation_results' x_variable = 'pressure_CH4' y_variable = 'pressure_CO2' analysis_range = [50, 100] # (in %) Ignore first X% of the total simulated time (e.g., initial equilibration) range_type = 'time' weights = 'time' min_molec_tof = 0 min_molec_selectivity = 100 min_coverage = 50 # (in %) Minimum coverage threshold for phase diagrams auto_title = True show_points = False show_colorbar = True fig, axs = plt.subplots(4, 3, figsize=(8.8, 8), sharey='row', sharex='col') # --- First row: TOF for different products --- for n, product in enumerate(['CO', 'H2', 'H2O']): plot_tof( ax=axs[0, n], scan_path=scan_path, x=x_variable, y=y_variable, gas_spec=product, min_molec=min_molec_tof, analysis_range=analysis_range, range_type=range_type, levels=np.logspace(-1, 4, num=11), auto_title=auto_title, show_points=show_points, show_colorbar=show_colorbar ) # --- Second row: Coverage for different site types --- for n, site_type in enumerate(['tC', 'tM', 'Pt']): plot_coverage( ax=axs[1, n], scan_path=scan_path, x=x_variable, y=y_variable, surf_spec='all', site_type=site_type, analysis_range=analysis_range, range_type=range_type, weights=weights, auto_title=auto_title, show_points=show_points, show_colorbar=show_colorbar ) # --- Third row: Phase diagram for different site types --- # Example grouping of species into labeled categories for the colorbar tick_labels = { '$CH_{x}$': ['CH3', 'CH3_Pt', 'CH2', 'CH2_Pt', 'CH', 'CH_Pt', 'C', 'C_Pt'], '$CHO/COH$': ['CHO', 'CHO_Pt', 'COH', 'COH_Pt'], '$CO$': ['CO', 'CO_Pt'], '$COOH$': ['COOH', 'COOH_Pt'], '$CO_{2}$': ['CO2', 'CO2_Pt'], '$H$': ['H', 'H_Pt'], '$H_{2}O$': ['H2O', 'H2O_Pt'], '$OH$': ['OH', 'OH_Pt'], '$O$': ['O', 'O_Pt'] } for n, site_type in enumerate(['tC', 'tM', 'Pt']): plot_phasediagram( ax=axs[2, n], scan_path=scan_path, x=x_variable, y=y_variable, site_type=site_type, min_coverage=min_coverage, tick_labels=tick_labels, analysis_range=analysis_range, range_type=range_type, auto_title=auto_title, show_points=show_points, show_colorbar=show_colorbar ) # --- Fourth row: Selectivity and Final Time --- # Selectivity plot_selectivity( ax=axs[3, 0], scan_path=scan_path, x=x_variable, y=y_variable, main_product='H2', side_products=['H2O'], min_molec=min_molec_selectivity, analysis_range=analysis_range, range_type=range_type, auto_title=auto_title, show_points=show_points, show_colorbar=show_colorbar ) # Final time plot_finaltime( ax=axs[3, 1], scan_path=scan_path, x=x_variable, y=y_variable, levels=np.logspace(-7, 7, num=15), auto_title=auto_title, show_points=show_points, show_colorbar=show_colorbar ) # Hide the third subplot in the last row axs[3, 2].axis('off') # Optional: clean up labels in intermediate subplots for i in range(3): for j in range(3): axs[i, j].set_xlabel('') for i in range(3): for j in range(1, 3): axs[i, j].set_ylabel('') plt.tight_layout() plt.savefig('multiple_heatmaps.png', dpi=300, bbox_inches='tight', transparent=False) plt.show() ```
Multiple heatmaps
--- ### Customization The size of axis ticks and font size of axis labels and titles can be adjusted with Matplotlib. Below is an example (shown here for a single heatmap, but the same approach applies to multi-plot figures as well): ```python import numpy as np import matplotlib.pyplot as plt from zacrostools.plot_functions.tof import plot_tof fig, axs = plt.subplots(1, figsize=(4.3, 3.5)) cp = plot_tof( ax=axs, scan_path='simulation_results', x='pressure_CH4', y='pressure_CO2', gas_spec='H2', min_molec=0, analysis_range=[50, 100], range_type='time', levels=np.logspace(-1, 4, num=11), auto_title=True, show_points=False, show_colorbar=False ) # Adjust size of axis ticks axs.tick_params(axis='both', which='major', labelsize=14) # Adjust font size of axis labels axs.set_xlabel(axs.get_xlabel(), fontsize=18) axs.set_ylabel(axs.get_ylabel(), fontsize=18) # Adjust font size and position of the title axs.set_title(axs.get_title(), fontsize=20, loc='center', pad=-170) # Create colorbar and adjust the size of its tick labels cbar = plt.colorbar(cp, ax=axs) cbar.ax.tick_params(labelsize=14) plt.tight_layout() plt.savefig('tof_heatmap_custom.png', dpi=300, bbox_inches='tight', transparent=False) plt.show() ```
TOF heatmap custom
```