def plot_phase_diagram(pd, show_unstable=False): """ Plot phase diagram for an specific composite :param pd: :param show_unstable: """ plotter = PDPlotter(pd, show_unstable=show_unstable) plotter.show()
def get_plot(self, **kwargs): """ Get plot with Pymatgen """ PDPlotter(self.pd, show_unstable=0, backend='matplotlib').get_plot(**kwargs) return plt
def Plot_Compositional_PhaseDiagram(self, label_stable=True): self.phasediagram_plot_object = PDPlotter(self.phasediagram) (lines, labels, unstable) = self.phasediagram_plot_object.pd_plot_data count = 1 newlabels = list() for x, y in lines: self.composition_phasediagram_plot_drawing.plot( x, y, "bo-", linewidth=3, markeredgecolor="b", markerfacecolor="r", markersize=10) for coords in sorted(labels.keys()): entry = labels[coords] label = entry.name if label_stable: if len(entry.composition.elements) == 1: self.composition_phasediagram_plot_drawing.text( coords[0], coords[1], label, fontdict=self.font) else: self.composition_phasediagram_plot_drawing.text( coords[0], coords[1], str(count), fontdict=self.font) newlabels.append("{} : {}".format(count, label)) count += 1 plt.figtext(0.01, 0.01, "\n".join(newlabels)) self.composition_phasediagram_plot_drawing.axis("off") self.composition_phasediagram_plot_canvas.draw()
def plot(self, show_unstable=True, show=True): """ Plot phase diagram. Args: show_unstable (float): Whether unstable phases will be plotted as well as red crosses. If a number > 0 is entered, all phases with ehull < show_unstable will be shown. show: True to show plot. Return: plotter object. """ from pymatgen.analysis.phase_diagram import PDPlotter plotter = PDPlotter(self.phasediagram, show_unstable=show_unstable) if show: plotter.show() return plotter
def get_phase_diagram_plot(self): """ Returns a phase diagram plot, as a matplotlib plot object. """ # set the font to Times, rendered with Latex plt.rc('font', **{'family': 'serif', 'serif': ['Times']}) plt.rc('text', usetex=True) # parse the composition space endpoints endpoints_line = self.lines[0].split() endpoints = [] for word in endpoints_line[::-1]: if word == 'endpoints:': break else: endpoints.append(Composition(word)) if len(endpoints) < 2: print('There must be at least 2 endpoint compositions to make a ' 'phase diagram.') quit() # parse the compositions and total energies of all the structures compositions = [] total_energies = [] for i in range(4, len(self.lines)): line = self.lines[i].split() compositions.append(Composition(line[1])) total_energies.append(float(line[2])) # make a list of PDEntries pdentries = [] for i in range(len(compositions)): pdentries.append(PDEntry(compositions[i], total_energies[i])) # make a CompoundPhaseDiagram compound_pd = CompoundPhaseDiagram(pdentries, endpoints) # make a PhaseDiagramPlotter pd_plotter = PDPlotter(compound_pd, show_unstable=50) return pd_plotter.get_plot(label_unstable=False)
def make_figure(pd): if pd is None: raise PreventUpdate pd = self.from_data(pd) dim = pd.dim if dim not in [2, 3, 4]: return "error" plotter = PDPlotter(pd) data = [] for line in plotter.pd_plot_data[0]: if dim == 2 or dim == 3: data.append( go.Scatter( x=list(line[0]), y=list(line[1]), # create all phase diagram lines mode="lines", hoverinfo="none", line={ "color": "rgba (0, 0, 0, 1)", "dash": "solid", "width": 3.0, }, showlegend=False, )) elif dim == 4: data.append( go.Scatter3d( x=list(line[0]), y=list(line[1]), z=list(line[2]), mode="lines", hoverinfo="none", line={ "color": "rgba (0, 0, 0, 1)", "dash": "solid", "width": 3.0, }, showlegend=False, )) data.append(self.create_unstable_markers(plotter, pd)) data.append(self.create_markers(plotter, pd)) fig = go.Figure(data=data) fig.layout = self.figure_layout(plotter, pd) return fig
def test_dim1(self): # Ensure that dim 1 PDs can eb generated. for el in ["Li", "Fe", "O2"]: entries = [e for e in self.entries if e.composition.reduced_formula == el] pd = PhaseDiagram(entries) self.assertEqual(len(pd.stable_entries), 1) for e in entries: decomp, ehull = pd.get_decomp_and_e_above_hull(e) self.assertGreaterEqual(ehull, 0) plotter = PDPlotter(pd) lines, stable_entries, unstable_entries = plotter.pd_plot_data self.assertEqual(lines[0][1], [0, 0])
def get_plot( self, show_unstable=0.2, label_stable=True, label_unstable=True, ordering=None, energy_colormap=None, process_attributes=False, label_uncertainties=False, ): """ Plot a PhaseDiagram. :param show_unstable: Whether unstable (above the hull) phases will be plotted. If a number > 0 is entered, all phases with e_hull < show_unstable (eV/atom) will be shown. :param label_stable: Whether to label stable compounds. :param label_unstable: Whether to label unstable compounds. :param ordering: Ordering of vertices (matplotlib backend only). :param energy_colormap: Colormap for coloring energy (matplotlib backend only). :param process_attributes: Whether to process the attributes (matplotlib backend only). :param plt: Existing plt object if plotting multiple phase diagrams ( matplotlib backend only). :param label_uncertainties: Whether to add error bars to the hull (plotly backend only). For binaries, this also shades the hull with the uncertainty window """ plotter = PDPlotter(self, backend="plotly", show_unstable=show_unstable) return plotter.get_plot( label_stable=label_stable, label_unstable=label_unstable, ordering=ordering, energy_colormap=energy_colormap, process_attributes=process_attributes, label_uncertainties=label_uncertainties, )
def Create_Compositional_PhaseDiagram(self): # Record all entries for the phase diagram phasediagram_entries = [] for compound in self.compounds_info.keys(): # Disregard elements not included in main compound if (compound in self.all_elements) and (compound not in self.elements_list): continue # Get the compound's composition compound_composition = {} if compound in self.elements_list: # Elemental material compound_composition[compound] = self.compounds_info[compound][ "dft_" + compound] else: # Compound material for element in self.compounds_info[compound]["elements_list"]: compound_composition[element] = self.compounds_info[ compound]["dft_" + element] # Get the compound's total energy compound_total_energy = self.compounds_info[compound][ "total_energy"] # Record to list of entries phasediagram_entries.append( PDEntry(compound_composition, compound_total_energy)) # Calculate compositional phase diagram (using pymatgen) # The output data structure is as follows: # lines --> List of arrays, each array is 2x2 for ternary (3x3 for quaternary, etc.), column vector represents point on phase diagram. # ex: array([ [0.3, 0.5], [1.0, 0.0] ]) is a line that goes from point [x=0.3, y=1.0] to point [x=0.5, y=0.0] # labels --> Dictionary with point-PDEntry pairs. self.pmg_phasediagram = PhaseDiagram(phasediagram_entries) self.pmg_phasediagram_plot_object = PDPlotter(self.pmg_phasediagram) (lines, labels, unstable) = self.pmg_phasediagram_plot_object.pd_plot_data # Record all lines and points of the compositional phase diagram self.lines = lines self.labels = labels
def get_stability_diagram(self, elements, size=None): """ Method to get stability diagram with 'get_chempot_range_map_plot' method in pymatgen Parameters ---------- elements : (list) List with strings of the elements to be used as free variables. size : (tuple) New size in inches. Returns ------- plt : Matplotlib object """ pd = self.pd elements = [Element(el) for el in elements] PDPlotter(pd).get_chempot_range_map_plot(elements) if size: fig = plt.gcf() fig.set_size_inches(size[0], size[1]) return plt
for match, header in search: total_energy_result = match[0] print("Total energy for: " + str(total_energy_result.structure.formula) + " (" + total_energy_result.structure.uc_formula + ") " + " is " + str(total_energy_result.total_energy)) entries += [ ComputedEntry(str(total_energy_result.structure.uc_formula), float(total_energy_result.total_energy)) ] # import random # for i in range(100): # ca=random.choice(range(10)) # ti=random.choice(range(10)) # o=random.choice(range(10)) # s=ca+ti+o # form = 'Ca'+str(ca)+'Ti'+str(ti)+'O'+str(o) # entries += [ComputedEntry(form, random.randrange(-10,0)*s)] if len(entries) == 0: sys.exit( "entries list is empty! Your sqlite database is missing total energies." ) else: for row in entries: print(entries) pd = PhaseDiagram(entries) plotter = PDPlotter(pd, show_unstable=False) plotter.show()
chempots_exp = { res: Chempots.from_dict(chempots_exp[res]).chempots for res in chempots_exp } # getting delta chempots chempots_boundary = { res: ca.get_chempots_delta(chempots_boundary[res]) for res in chempots_boundary } chempots_exp = { res: ca.get_chempots_delta(chempots_exp[res]) for res in chempots_exp } pd = PDHandler(computed_phases).phase_diagram() pdplotter = PDPlotter(pd) #building set of points points_boundary = {} for res in chempots_boundary: points_boundary[res] = (chempots_boundary[res][Element('Na')], chempots_boundary[res][Element('Nb')]) points_exp = {} for res in chempots_exp: points_exp[res] = (chempots_exp[res][Element('Na')], chempots_exp[res][Element('Nb')]) pdplotter.get_chempot_range_map_plot([Element('Na'), Element('Nb')]) plotcustom = PDPlotterAdder(ca) plotcustom.add_points(points_boundary)
#Draws phase diagram for chemical system #!/usr/bin/env python from pymatgen.ext.matproj import MPRester from pymatgen.analysis.phase_diagram import * from pymatgen.analysis.phase_diagram import PDPlotter #This initializes the REST adaptor. Put your own API key in. a = MPRester( "API_ID") #Go to materialsproject.org to create account and get API key #Entries are the basic unit for thermodynamic and other analyses in pymatgen. #This gets all entries belonging to the Ca-C-O system. # entries = a.get_entries_in_chemsys(['Ca', 'C', 'O']) entries = a.get_entries_in_chemsys(['Li', 'Mn', 'O']) #With entries, you can do many sophisticated analyses, like creating phase diagrams. pd = PhaseDiagram(entries) plotter = PDPlotter(pd) plotter.show()
def plot_hull(self, df, new_result_ids, filename=None, finalize=False): """ Generate plots of convex hulls for each of the runs Args: df (DataFrame): dataframe with formation energies and formulas new_result_ids ([]): list of new result ids (i. e. indexes in the updated dataframe) filename (str): filename to output, if None, no file output is produced finalize (bool): flag indicating whether to include all new results Returns: (pyplot): plotter instance """ # Generate all entries total_comp = Composition(df['Composition'].sum()) if len(total_comp) > 4: warnings.warn( "Number of elements too high for phase diagram plotting") return None filtered = filter_dataframe_by_composition(df, total_comp) filtered = filtered[['delta_e', 'Composition']] filtered = filtered.dropna() # Create computed entry column with un-normalized energies filtered["entry"] = [ ComputedEntry( Composition(row["Composition"]), row["delta_e"] * Composition(row["Composition"]).num_atoms, entry_id=index, ) for index, row in filtered.iterrows() ] ids_prior_to_run = list(set(filtered.index) - set(new_result_ids)) if not ids_prior_to_run: warnings.warn( "No prior data, prior phase diagram cannot be constructed") return None # Create phase diagram based on everything prior to current run entries = filtered.loc[ids_prior_to_run]["entry"].dropna() # Filter for nans by checking if it's a computed entry pg_elements = sorted(total_comp.keys()) pd = PhaseDiagram(entries, elements=pg_elements) plotkwargs = { "markerfacecolor": "white", "markersize": 7, "linewidth": 2, } if finalize: plotkwargs.update({"linestyle": "--"}) else: plotkwargs.update({"linestyle": "-"}) plotter = PDPlotter(pd, backend='matplotlib', **plotkwargs) getplotkwargs = {"label_stable": False} if finalize else {} plot = plotter.get_plot(**getplotkwargs) # Get valid results valid_results = [ new_result_id for new_result_id in new_result_ids if new_result_id in filtered.index ] if finalize: # If finalize, we'll reset pd to all entries at this point to # measure stabilities wrt. the ultimate hull. pd = PhaseDiagram(filtered["entry"].values, elements=pg_elements) plotter = PDPlotter(pd, backend="matplotlib", **{ "markersize": 0, "linestyle": "-", "linewidth": 2 }) plot = plotter.get_plot(plt=plot) for entry in filtered["entry"][valid_results]: decomp, e_hull = pd.get_decomp_and_e_above_hull( entry, allow_negative=True) if e_hull < self.hull_distance: color = "g" marker = "o" markeredgewidth = 1 else: color = "r" marker = "x" markeredgewidth = 1 # Get coords coords = [ entry.composition.get_atomic_fraction(el) for el in pd.elements ][1:] if pd.dim == 2: coords = coords + [pd.get_form_energy_per_atom(entry)] if pd.dim == 3: coords = triangular_coord(coords) elif pd.dim == 4: coords = tet_coord(coords) plot.plot(*coords, marker=marker, markeredgecolor=color, markerfacecolor="None", markersize=11, markeredgewidth=markeredgewidth) if filename is not None: plot.savefig(filename, dpi=70) plot.close()
def present(self, df=None, new_result_ids=None, all_result_ids=None, filename=None, save_hull_distance=False, finalize=False): """ Generate plots of convex hulls for each of the runs Args: df (DataFrame): dataframe with formation energies, compositions, ids new_result_ids ([]): list of new result ids (i. e. indexes in the updated dataframe) all_result_ids ([]): list of all result ids associated with the current run filename (str): filename to output, if None, no file output is produced Returns: (pyplot): plotter instance """ df = df if df is not None else self.df new_result_ids = new_result_ids if new_result_ids is not None \ else self.new_result_ids all_result_ids = all_result_ids if all_result_ids is not None \ else self.all_result_ids # TODO: consolidate duplicated code here # Generate all entries comps = df.loc[all_result_ids]['Composition'].dropna() system_elements = [] for comp in comps: system_elements += list(Composition(comp).as_dict().keys()) elems = set(system_elements) if len(elems) > 4: warnings.warn( "Number of elements too high for phase diagram plotting") return None ind_to_include = [] for ind in df.index: if set(Composition( df.loc[ind]['Composition']).as_dict().keys()).issubset( elems): ind_to_include.append(ind) _df = df.loc[ind_to_include] # Create computed entry column _df['entry'] = [ ComputedEntry( Composition(row['Composition']), row['delta_e'] * Composition( row['Composition']).num_atoms, # un-normalize the energy entry_id=index) for index, row in _df.iterrows() ] # Partition ids into sets of prior to CAMD run, from CAMD but prior to # current iteration, and new ids ids_prior_to_camd = list(set(_df.index) - set(all_result_ids)) ids_prior_to_run = list(set(all_result_ids) - set(new_result_ids)) # Create phase diagram based on everything prior to current run entries = list(_df.loc[ids_prior_to_run + ids_prior_to_camd]['entry']) # Filter for nans by checking if it's a computed entry entries = [ entry for entry in entries if isinstance(entry, ComputedEntry) ] pg_elements = [Element(el) for el in sorted(elems)] pd = PhaseDiagram(entries, elements=pg_elements) plotkwargs = { "markerfacecolor": "white", "markersize": 7, "linewidth": 2, } if finalize: plotkwargs.update({'linestyle': '--'}) else: plotkwargs.update({'linestyle': '-'}) plotter = PDPlotter(pd, **plotkwargs) getplotkwargs = {"label_stable": False} if finalize else {} plot = plotter.get_plot(**getplotkwargs) # Get valid results valid_results = [ new_result_id for new_result_id in new_result_ids if new_result_id in _df.index ] if finalize: # If finalize, we'll reset pd to all entries at this point # to measure stabilities wrt. the ultimate hull. pd = PhaseDiagram(_df['entry'].values, elements=pg_elements) plotter = PDPlotter( pd, **{ "markersize": 0, "linestyle": "-", "linewidth": 2 }) plot = plotter.get_plot(plt=plot) for entry in _df['entry'][valid_results]: decomp, e_hull = pd.get_decomp_and_e_above_hull( entry, allow_negative=True) if e_hull < self.hull_distance: color = 'g' marker = 'o' markeredgewidth = 1 else: color = 'r' marker = 'x' markeredgewidth = 1 # Get coords coords = [ entry.composition.get_atomic_fraction(el) for el in pd.elements ][1:] if pd.dim == 2: coords = coords + [pd.get_form_energy_per_atom(entry)] if pd.dim == 3: coords = triangular_coord(coords) elif pd.dim == 4: coords = tet_coord(coords) plot.plot(*coords, marker=marker, markeredgecolor=color, markerfacecolor="None", markersize=11, markeredgewidth=markeredgewidth) if filename is not None: plot.savefig(filename, dpi=70) plot.close() if filename is not None and save_hull_distance: if self.stabilities is None: print("ERROR: No stability information in analyzer.") return None with open(filename.split(".")[0] + '.json', 'w') as f: json.dump(self.stabilities, f)
def make_figure(pd): pd = self.from_data(pd) dim = pd.dim plotter = PDPlotter(pd) # create plotter object using pymatgen # print(pd.stable_entries) if dim not in [2, 3, 4]: raise ValueError( "Structure contains {} components." " Phase diagrams can only be created with 2, 3, or 4 components".format( str(dim) ) ) data = [] # initialize plot data list if dim == 2: for line in plotter.pd_plot_data[0]: data.append( go.Scatter( x=list(line[0]), y=list(line[1]), # create all phase diagram lines mode="lines", hoverinfo="none", line={ "color": "rgba (0, 0, 0, 1)", "dash": "solid", "width": 3.0, }, showlegend=False, ) ) x_list = [] y_list = [] text_list = [] unstable_xy_list = list(plotter.pd_plot_data[2].values()) unstable_entry_list = list(plotter.pd_plot_data[2].keys()) for unstable_xy, unstable_entry in zip( unstable_xy_list, unstable_entry_list ): x_list.append(unstable_xy[0]) y_list.append(unstable_xy[1]) mpid = unstable_entry.entry_id formula = list(unstable_entry.composition.reduced_formula) e_above_hull = round(pd.get_e_above_hull(unstable_entry), 3) # add formula subscripts s = [] for char in formula: if char.isdigit(): s.append("<sub>" + char + "</sub>") else: s.append(char) clean_formula = "" clean_formula = clean_formula.join(s) energy = round(pd.get_form_energy_per_atom(unstable_entry), 3) text_list.append( f"{clean_formula} ({mpid})<br>" f"{energy} eV ({e_above_hull} eV)" ) data.append( go.Scatter( x=x_list, y=y_list, mode="markers", hoverinfo="text", hovertext=text_list, visible="legendonly", name="Unstable", marker=dict(color="#ff0000", size=12, symbol="x"), ) ) elif dim == 3: for line in plotter.pd_plot_data[0]: data.append( go.Scatter( x=list(line[0]), y=list(line[1]), # create all phase diagram lines mode="lines", hoverinfo="none", line={ "color": "rgba (0, 0, 0, 1)", "dash": "solid", "width": 3.0, }, showlegend=False, ) ) x_list = [] y_list = [] xy_list = [] text_list = [] unstable_xy_list = list(plotter.pd_plot_data[2].values()) unstable_entry_list = list(plotter.pd_plot_data[2].keys()) for unstable_xy, unstable_entry in zip( unstable_xy_list, unstable_entry_list ): mpid = unstable_entry.entry_id formula = unstable_entry.composition.reduced_formula energy = round(pd.get_form_energy_per_atom(unstable_entry), 3) e_above_hull = round(pd.get_e_above_hull(unstable_entry), 3) s = [] for char in formula: if char.isdigit(): s.append("<sub>" + char + "</sub>") else: s.append(char) clean_formula = "" clean_formula = clean_formula.join(s) if unstable_xy not in xy_list: x_list.append(unstable_xy[0]) y_list.append(unstable_xy[1]) xy_list.append(unstable_xy) text_list.append( clean_formula + " (" + mpid + ")" "<br>" + str(energy) + " eV" + " (" + str(e_above_hull) + " eV" + ")" ) else: index = xy_list.index(unstable_xy) text_list[index] += ( "<br>" + clean_formula + "<br>" + str(energy) + " eV" + " (" + str(e_above_hull) + " eV" + ")" ) data.append( go.Scatter( x=x_list, y=y_list, mode="markers", hoverinfo="text", hovertext=text_list, visible="legendonly", name="Unstable", marker=dict(color="#ff0000", size=12, symbol="x"), ) ) elif dim == 4: for line in plotter.pd_plot_data[0]: data.append( go.Scatter3d( x=list(line[0]), y=list(line[1]), z=list(line[2]), # create all phase diagram lines mode="lines", hoverinfo="none", line={ "color": "rgba (0, 0, 0, 1)", "dash": "solid", "width": 3.0, }, showlegend=False, ) ) x_list = [] y_list = [] z_list = [] xyz_list = [] text_list = [] unstable_xyz_list = list(plotter.pd_plot_data[2].values()) unstable_entry_list = list(plotter.pd_plot_data[2].keys()) for unstable_xyz, unstable_entry in zip( unstable_xyz_list, unstable_entry_list ): mpid = unstable_entry.entry_id formula = unstable_entry.composition.reduced_formula energy = round(pd.get_form_energy_per_atom(unstable_entry), 3) e_above_hull = round(pd.get_e_above_hull(unstable_entry), 3) s = [] for char in formula: if char.isdigit(): s.append("<sub>" + char + "</sub>") else: s.append(char) clean_formula = "" clean_formula = clean_formula.join(s) if unstable_xyz not in xyz_list: x_list.append(unstable_xyz[0]) y_list.append(unstable_xyz[1]) z_list.append(unstable_xyz[2]) xyz_list.append(unstable_xyz) text_list.append( clean_formula + " (" + mpid + ")" + "<br>" + str(energy) + " eV" + " (" + str(e_above_hull) + " eV" + ")" ) else: index = xyz_list.index(unstable_xyz) text_list[index] += ( "<br>" + clean_formula + "<br>" + str(energy) + " eV" + " (" + str(e_above_hull) + " eV" + ")" ) data.append( go.Scatter3d( x=x_list, y=y_list, z=z_list, mode="markers", hoverinfo="text", hovertext=text_list, visible="legendonly", name="Unstable", marker=dict(color="#ff0000", size=4, symbol="x"), ) ) data.append(self.create_markers(plotter, pd)) fig = go.Figure(data=data) fig.layout = self.figure_layout(plotter, pd) return fig
lines=f.readlines() content=(lines[3]).split(" ") for val in content: if val != '' and val !='\n' and val !='\r\n': list_el.append(val) for i in range(0,len(list_el)): if i!=0: element_ff.append(list_el[i]) with MPRester(MAPI_KEY) as m: data = m.get_entries_in_chemsys(element_ff,inc_structure='final', property_data=["unit_cell_formula","material_id","icsd_id","spacegroup","energy_per_atom","formation_energy_per_atom","pretty_formula","band_gap","total_magnetization","e_above_hull"]) if (len(element_ff)>1): try: entries = m.get_entries_in_chemsys(element_ff) pd = PhaseDiagram(entries) plotter = PDPlotter(pd, show_unstable=True) image=str(ff)+str("_DFT")+str(".jpg") plotter.write_image(image) except: pass for d in data: x=d.data["material_id"] structure = m.get_structure_by_material_id(x) comment=str("bulk@")+str(x) folder2=str(os.getcwd())+str("/")+str(comment)+str("_fold") if not os.path.exists(folder2): os.makedirs(str(folder2)) print ("folder2=",folder2) cwd2=str(os.getcwd())
def plot_pd(pd, show_unstable=False): plotter = PDPlotter(pd, show_unstable=show_unstable) # plotter = PDPlotter(pd, show_unstable=0.03) plotter.show()
comp = Composition(phase) # getting entry for PD Object entry = PDEntry(comp, computed_phases[phase]) # building list of entries entries.append(entry) # getting PD from list of entries pd = PhaseDiagram(entries) # get distance from convex hull for cubic phase comp = Composition('NaNbO3') energy = -38.26346361 entry = PDEntry(comp, energy) cubic_instability = pd.get_e_above_hull(entry) pd_dict = pd.as_dict() # Getting Plot plt = PDPlotter(pd, show_unstable=False) # you can also try show_unstable=True #plt_data = plt.pd_plot_data # getting plot for chem potential - variables 'fontsize' for labels size and 'plotsize' for fig size have been added (not present in original pymatgen) to get_chempot_range_map_plot function chem_pot_plot = plt.get_chempot_range_map_plot( [Element("Na"), Element("Nb")], fontsize=14, plotsize=1.5) #plt.write_image("chem_pot_{}.png".format('-'.join(system)), "png") chem_pot_plot.savefig(f'chem_pot_{system_name}.png') # save figure # getting plot for PD - variables 'fontsize' for labels size and plotsize for fig size have been added (not present in original pymatgen) to get_plot function pd_plot = plt.get_plot(label_stable=True, fontsize=24, plotsize=3) pd_plot.savefig(f'PD_{system_name}.png')
class PDPlotterTest(unittest.TestCase): def setUp(self): entries = list( EntrySet.from_csv(os.path.join(module_dir, "pdentries_test.csv"))) self.pd_ternary = PhaseDiagram(entries) self.plotter_ternary_mpl = PDPlotter(self.pd_ternary, backend="matplotlib") self.plotter_ternary_plotly = PDPlotter(self.pd_ternary, backend="plotly") entrieslio = [e for e in entries if "Fe" not in e.composition] self.pd_binary = PhaseDiagram(entrieslio) self.plotter_binary_mpl = PDPlotter(self.pd_binary, backend="matplotlib") self.plotter_binary_plotly = PDPlotter(self.pd_binary, backend="plotly") entries.append(PDEntry("C", 0)) self.pd_quaternary = PhaseDiagram(entries) self.plotter_quaternary_mpl = PDPlotter(self.pd_quaternary, backend="matplotlib") self.plotter_quaternary_plotly = PDPlotter(self.pd_quaternary, backend="plotly") def test_pd_plot_data(self): (lines, labels, unstable_entries) = self.plotter_ternary_mpl.pd_plot_data self.assertEqual(len(lines), 22) self.assertEqual( len(labels), len(self.pd_ternary.stable_entries), "Incorrect number of lines generated!", ) self.assertEqual( len(unstable_entries), len(self.pd_ternary.all_entries) - len(self.pd_ternary.stable_entries), "Incorrect number of lines generated!", ) (lines, labels, unstable_entries) = self.plotter_quaternary_mpl.pd_plot_data self.assertEqual(len(lines), 33) self.assertEqual(len(labels), len(self.pd_quaternary.stable_entries)) self.assertEqual( len(unstable_entries), len(self.pd_quaternary.all_entries) - len(self.pd_quaternary.stable_entries), ) (lines, labels, unstable_entries) = self.plotter_binary_mpl.pd_plot_data self.assertEqual(len(lines), 3) self.assertEqual(len(labels), len(self.pd_binary.stable_entries)) def test_mpl_plots(self): # Some very basic ("non")-tests. Just to make sure the methods are callable. self.plotter_binary_mpl.get_plot().close() self.plotter_ternary_mpl.get_plot().close() self.plotter_quaternary_mpl.get_plot().close() self.plotter_ternary_mpl.get_contour_pd_plot().close() self.plotter_ternary_mpl.get_chempot_range_map_plot( [Element("Li"), Element("O")]).close() self.plotter_ternary_mpl.plot_element_profile( Element("O"), Composition("Li2O")).close() def test_plotly_plots(self): # Also very basic tests. Ensures callability and 2D vs 3D properties. self.plotter_binary_plotly.get_plot() self.plotter_ternary_plotly.get_plot() self.plotter_quaternary_plotly.get_plot()
############################################################################### MAPI_KEY = 'DSR45TfHVuyuB1WvP1' # You must change this to your Materials API key! (or set MAPI_KEY env variable) mpr = MPRester(MAPI_KEY) # object for connecting to MP Rest interface compat = MaterialsProjectCompatibility( ) # sets energy corrections and +U/pseudopotential choice # Create phase diagram! unprocessed_entries = mpr.get_entries_in_chemsys(system) processed_entries = compat.process_entries( unprocessed_entries) # filter and add energy corrections pd = PhaseDiagram(processed_entries) pd_dict = pd.as_dict() # Plot! plt = PDPlotter(pd, show_unstable=False) # you can also try show_unstable=True #plt.get_chempot_range_map_plot([Element("Na"), Element("Nb")]) #plt.show() # create dictionary for stable phases and material ID stable_phases = {} stable_entries = pd.stable_entries print('Stable Entries (formula, materials_id)\n--------') for e in pd.stable_entries: print(e.composition.reduced_formula, e.entry_id) stable_phases.update({e.composition.reduced_formula: e.entry_id}) ############################################################################### print('')
def setUp(self): entries = list( EntrySet.from_csv(os.path.join(module_dir, "pdentries_test.csv"))) self.pd_ternary = PhaseDiagram(entries) self.plotter_ternary_mpl = PDPlotter(self.pd_ternary, backend="matplotlib") self.plotter_ternary_plotly = PDPlotter(self.pd_ternary, backend="plotly") entrieslio = [e for e in entries if "Fe" not in e.composition] self.pd_binary = PhaseDiagram(entrieslio) self.plotter_binary_mpl = PDPlotter(self.pd_binary, backend="matplotlib") self.plotter_binary_plotly = PDPlotter(self.pd_binary, backend="plotly") entries.append(PDEntry("C", 0)) self.pd_quaternary = PhaseDiagram(entries) self.plotter_quaternary_mpl = PDPlotter(self.pd_quaternary, backend="matplotlib") self.plotter_quaternary_plotly = PDPlotter(self.pd_quaternary, backend="plotly")
from pymatgen.entries.compatibility import MaterialsProjectCompatibility from pymatgen.analysis.phase_diagram import PhaseDiagram, PDPlotter import pandas as pd # Assimilate VASP calculations into ComputedEntry object. Let's assume that # the calculations are for a series of new LixFeyOz phases that we want to # know the phase stability. drone = VaspToComputedEntryDrone() queen = BorgQueen(drone, rootpath=".") entries = queen.get_data() # Obtain all existing Li-Fe-O phases using the Materials Project REST API with MPRester("NKnnBgWXU5o1S5ogiJGE") as m: mp_entries = m.get_entries_in_chemsys(["Mg", "Al", "O"]) # Combined entry from calculated run with Materials Project entries entries.extend(mp_entries) # Process entries using the MaterialsProjectCompatibility compat = MaterialsProjectCompatibility() entries = compat.process_entries(entries) # Generate and plot Li-Fe-O phase diagram pd = PhaseDiagram(entries) plotter = PDPlotter(pd) # plotter.show() results = m.query("**2O4", ['pretty_formula', 'spacegroup', 'energy']) print(results) # df = pd.DataFrame(results) # df.to_excel('23456.xlsx', sheet_name='Materials_Project', index=False, header=['Structure'], na_rep="NULL")