Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: Add phase legend generator in dataplot #265

Merged
merged 3 commits into from
Feb 19, 2025

Conversation

RushiGong
Copy link
Contributor

This PR updates the fixed phase_legend function in dataplot to legend_generator. This enhancement allows customized phase legend generator used in pycalphad.mapping.plotting can be integrated into dataplot for plotting ZPF data in the phase diagram.

@bocklund
Copy link
Member

bocklund commented Feb 19, 2025

Thanks, Rushi! @cjkunselman18 was just hitting this a week or two ago, so this is really timely.

Just to add some context, the root cause for discrepancies is that the mapping code in PyCalphad builds the phase list differently than ESPEI's dataplot.

  • In PyCalphad, the legend phases are generated by a combination of (1) phases that are stable in the diagram and (2) by creating distinct "phases" for composition sets in miscibility gaps (e.g. "BCC_A2" and "BCC_A2#2").
  • In ESPEI's dataplot, the legend contains all the phases the user passed in and any additional phases we found in the datasets that match queries. It also adds in all the symbols for references in the user's datasets.

The dynamic nature of the former can get out of sync with the latter, and therefore the colors and handles can get out of sync. Since PyCalphad plotting functions and ESPEI's dataplot are both intended (at least in their current designs) to be able to be used independently of each other, it makes sense to introduce the legend_generator API to dataplot as well.

Here's some demo code for how to use this, for reference. This could be done other ways, but this is a quick and dirty method that illustrates the idea.

import matplotlib.pyplot as plt
from pycalphad import Database, binplot, variables as v
from espei.datasets import load_datasets, recursive_glob
from espei.plot import dataplot

datasets = load_datasets(recursive_glob("../input-data"))

dbf = Database("Cr-Fe-mcmc.tdb")
comps = ["CR", "FE", "VA"]
phases = list(dbf.phases.keys())
conds = {v.P: 101325, v.T: (700, 2200, 10), v.X("CR"): (0, 1, 0.01)}

# we need to account for the fact that when the mapping code calls this
# function that there may be additional phase boundaries with #N suffix
# (N being some integer).
LEGEND_PHASES = sorted(phases)
from pycalphad.plot.utils import phase_legend
import matplotlib.patches as mpatches
def my_legend_generator_remap(_phases):
    # use the global list of phases, not the one passed to ensure consistency
    # between legends generated by binplot and dataplot
    global_phases = sorted(LEGEND_PHASES)
    handles, colors = phase_legend(global_phases)
    # next we remap any #N-suffixed composition sets to the color of the un-suffixed phase
    new_phases = sorted(set(_phases) - set(global_phases))
    for phase_name in new_phases:
        # assumes that there's exactly one "#" and it is a suffix (not part of the phase name otherwise)
        phase_name_no_suffix = phase_name.split("#")[0]
        # update colors and handles for the suffixed phase to the un-suffixed phase
        colors[phase_name] = colors[phase_name_no_suffix]
        handles.append(mpatches.Patch(color=colors[phase_name], label=phase_name))
    return handles, colors

fig, ax = plt.subplots()
binplot(dbf, comps, phases, conds, plot_kwargs=dict(ax=ax, legend_generator=my_legend_generator_remap))
dataplot(comps, phases, conds, datasets, ax=ax, legend_generator=my_legend_generator_remap)
ax.set_title("Cr-Fe MCMC")
ax.set_ylim(conds[v.T][0], conds[v.T][1])
ax.set_xlabel("X(Cr)")
ax.set_ylabel("Temperature (K)")
fig.show()

image

For future work, maybe there's a version of dataplot that is a little smarter and checks for an existing legend from mapping and uses it appropriately (extending it with reference information).

@bocklund bocklund merged commit 914d200 into PhasesResearchLab:master Feb 19, 2025
11 checks passed
@RushiGong RushiGong deleted the legend_generator branch February 19, 2025 23:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants