2021-10-21 14:41:10 +02:00
import matplotlib . pyplot as plt
2021-11-08 17:24:58 +01:00
from matplotlib . ticker import ( MultipleLocator , FormatStrFormatter , AutoMinorLocator )
import pandas as pd
import numpy as np
import math
import beamtime . xrd as xrd
def plot_diffractogram ( path , kind , options = None ) :
# Prepare plot, and read and process data
fig , ax = prepare_diffractogram_plot ( options = options )
diffractogram = xrd . io . read_data ( path = path , kind = kind , options = options )
# Update options
required_options = [ ' x_vals ' , ' y_vals ' , ' scatter ' ]
default_options = {
' x_vals ' : ' 2th ' ,
' y_vals ' : ' I ' ,
' scatter ' : False
}
options = update_options ( options = options , required_options = required_options , default_options = default_options )
if options [ ' scatter ' ] :
diffractogram . plot ( x = options [ ' x_vals ' ] , y = options [ ' y_vals ' ] , ax = ax , kind = ' scatter ' )
else :
diffractogram . plot ( x = options [ ' x_vals ' ] , y = options [ ' y_vals ' ] , ax = ax )
fig , ax = prettify_diffractogram_plot ( fig = fig , ax = ax , options = options )
return diffractogram , fig , ax
def prepare_diffractogram_plot ( options = None ) :
# First take care of the options for plotting - set any values not specified to the default values
required_options = [ ' columns ' , ' width ' , ' height ' , ' format ' , ' dpi ' , ' facecolor ' ]
default_options = { ' columns ' : 1 , ' width ' : 14 , ' format ' : ' golden_ratio ' , ' dpi ' : None , ' facecolor ' : ' w ' }
# Define the required sizes
required_sizes = [ ' lines ' , ' axes ' ]
# If none are set at all, just pass the default_options
if not options :
options = default_options
options [ ' height ' ] = options [ ' width ' ] * ( math . sqrt ( 5 ) - 1 ) / 2
options [ ' figsize ' ] = ( options [ ' width ' ] , options [ ' height ' ] )
# Define default sizes
default_sizes = {
' lines ' : 3 * options [ ' columns ' ] ,
' axes ' : 3 * options [ ' columns ' ]
}
# Initialise dictionary if it doesn't exist
if not ' sizes ' in options . keys ( ) :
options [ ' sizes ' ] = { }
# Update dictionary with default values where none is supplied
for size in required_sizes :
if size not in options [ ' sizes ' ] :
options [ ' sizes ' ] [ size ] = default_sizes [ size ]
# If options is passed, go through to fill out the rest.
else :
# Start by setting the width:
if ' width ' not in options . keys ( ) :
options [ ' width ' ] = default_options [ ' width ' ]
# Then set height - check options for format. If not given, set the height to the width scaled by the golden ratio - if the format is square, set the same. This should possibly allow for the tweaking of custom ratios later.
if ' height ' not in options . keys ( ) :
if ' format ' not in options . keys ( ) :
options [ ' height ' ] = options [ ' width ' ] * ( math . sqrt ( 5 ) - 1 ) / 2
elif options [ ' format ' ] == ' square ' :
options [ ' height ' ] = options [ ' width ' ]
options [ ' figsize ' ] = ( options [ ' width ' ] , options [ ' height ' ] )
# After height and width are set, go through the rest of the options to make sure that all the required options are filled
for option in required_options :
if option not in options . keys ( ) :
options [ option ] = default_options [ option ]
fig , ax = plt . subplots ( figsize = ( options [ ' figsize ' ] ) , dpi = options [ ' dpi ' ] , facecolor = options [ ' facecolor ' ] )
plt . rc ( ' lines ' , linewidth = options [ ' sizes ' ] [ ' lines ' ] )
plt . rc ( ' axes ' , linewidth = options [ ' sizes ' ] [ ' axes ' ] )
return fig , ax
def prettify_diffractogram_plot ( fig , ax , options = None ) :
##################################################################
######################### UPDATE OPTIONS #########################
##################################################################
# Define the required options
required_options = [
' columns ' ,
' xticks ' , ' yticks ' ,
' units ' ,
' show_major_ticks ' , ' show_minor_ticks ' , ' show_tick_labels ' ,
' xlim ' , ' ylim ' ,
' hide_x_axis ' , ' hide_y_axis ' ,
' positions ' ,
' xlabel ' , ' ylabel ' ,
' sizes ' ,
' title '
]
# Define the default options
default_options = {
' columns ' : 1 ,
' xticks ' : [ 10 , 5 ] , ' yticks ' : [ 10000 , 5000 ] ,
' units ' : { ' 2th ' : ' $^o$ ' , ' I ' : ' arb. u. ' } ,
' show_major_ticks ' : [ True , False , True , False ] , ' show_minor_ticks ' : [ True , False , True , False ] , ' show_tick_labels ' : [ True , False , False , False ] ,
' xlim ' : None , ' ylim ' : None ,
' hide_x_axis ' : False , ' hide_y_axis ' : False ,
' positions ' : { ' xaxis ' : ' bottom ' , ' yaxis ' : ' left ' } ,
' xlabel ' : None , ' ylabel ' : None ,
' sizes ' : None ,
' title ' : None
}
options = update_options ( options , required_options , default_options )
##################################################################
########################## DEFINE SIZES ##########################
##################################################################
# Define the required sizes
required_sizes = [
' labels ' ,
' legend ' ,
' title ' ,
' line ' , ' axes ' ,
' tick_labels ' ,
' major_ticks ' , ' minor_ticks ' ]
# Define default sizes
default_sizes = {
' labels ' : 30 * options [ ' columns ' ] ,
' legend ' : 30 * options [ ' columns ' ] ,
' title ' : 30 * options [ ' columns ' ] ,
' line ' : 3 * options [ ' columns ' ] ,
' axes ' : 3 * options [ ' columns ' ] ,
' tick_labels ' : 30 * options [ ' columns ' ] ,
' major_ticks ' : 20 * options [ ' columns ' ] ,
' minor_ticks ' : 10 * options [ ' columns ' ]
}
# Initialise dictionary if it doesn't exist
if not options [ ' sizes ' ] :
options [ ' sizes ' ] = { }
# Update dictionary with default values where none is supplied
for size in required_sizes :
if size not in options [ ' sizes ' ] :
options [ ' sizes ' ] [ size ] = default_sizes [ size ]
##################################################################
########################## AXIS LABELS ###########################
##################################################################
if not options [ ' xlabel ' ] :
options [ ' xlabel ' ] = prettify_labels ( options [ ' x_vals ' ] ) + ' [ {} ] ' . format ( options [ ' units ' ] [ options [ ' x_vals ' ] ] )
else :
options [ ' xlabel ' ] = options [ ' xlabel ' ] + ' [ {} ] ' . format ( options [ ' units ' ] [ options [ ' x_vals ' ] ] )
if not options [ ' ylabel ' ] :
options [ ' ylabel ' ] = prettify_labels ( options [ ' y_vals ' ] ) + ' [ {} ] ' . format ( options [ ' units ' ] [ options [ ' y_vals ' ] ] )
else :
options [ ' ylabel ' ] = options [ ' ylabel ' ] + ' [ {} ] ' . format ( options [ ' units ' ] [ options [ ' y_vals ' ] ] )
ax . set_xlabel ( options [ ' xlabel ' ] , size = options [ ' sizes ' ] [ ' labels ' ] )
ax . set_ylabel ( options [ ' ylabel ' ] , size = options [ ' sizes ' ] [ ' labels ' ] )
##################################################################
###################### TICK MARKS & LABELS #######################
##################################################################
ax . tick_params (
direction = ' in ' ,
which = ' major ' ,
bottom = options [ ' show_major_ticks ' ] [ 0 ] , labelbottom = options [ ' show_tick_labels ' ] [ 0 ] ,
left = options [ ' show_major_ticks ' ] [ 1 ] , labelleft = options [ ' show_tick_labels ' ] [ 1 ] ,
top = options [ ' show_major_ticks ' ] [ 2 ] , labeltop = options [ ' show_tick_labels ' ] [ 2 ] ,
right = options [ ' show_major_ticks ' ] [ 3 ] , labelright = options [ ' show_tick_labels ' ] [ 3 ] ,
length = options [ ' sizes ' ] [ ' major_ticks ' ] ,
width = options [ ' sizes ' ] [ ' axes ' ] )
ax . tick_params ( direction = ' in ' , which = ' minor ' , bottom = options [ ' show_minor_ticks ' ] [ 0 ] , left = options [ ' show_minor_ticks ' ] [ 1 ] , top = options [ ' show_minor_ticks ' ] [ 2 ] , right = options [ ' show_minor_ticks ' ] [ 3 ] , length = options [ ' sizes ' ] [ ' minor_ticks ' ] , width = options [ ' sizes ' ] [ ' axes ' ] )
if options [ ' positions ' ] [ ' yaxis ' ] == ' right ' :
ax . yaxis . set_label_position ( " right " )
ax . yaxis . tick_right ( )
if options [ ' hide_x_axis ' ] :
ax . axes . xaxis . set_visible ( False )
if options [ ' hide_y_axis ' ] :
ax . axes . yaxis . set_visible ( False )
# Otherwise apply user input
if options [ ' xticks ' ] :
major_xtick = options [ ' xticks ' ] [ 0 ]
minor_xtick = options [ ' xticks ' ] [ 1 ]
if options [ ' yticks ' ] :
major_ytick = options [ ' yticks ' ] [ 0 ]
minor_ytick = options [ ' yticks ' ] [ 1 ]
# Apply values
ax . xaxis . set_major_locator ( MultipleLocator ( major_xtick ) )
ax . xaxis . set_minor_locator ( MultipleLocator ( minor_xtick ) )
ax . yaxis . set_major_locator ( MultipleLocator ( major_ytick ) )
ax . yaxis . set_minor_locator ( MultipleLocator ( minor_ytick ) )
# SET FONTSIZE OF TICK LABELS
plt . xticks ( fontsize = options [ ' sizes ' ] [ ' tick_labels ' ] )
plt . yticks ( fontsize = options [ ' sizes ' ] [ ' tick_labels ' ] )
##################################################################
########################## AXES LIMITS ###########################
##################################################################
if options [ ' xlim ' ] :
plt . xlim ( options [ ' xlim ' ] )
if options [ ' ylim ' ] :
plt . ylim ( options [ ' ylim ' ] )
##################################################################
############################# TITLE ##############################
##################################################################
if options [ ' title ' ] :
ax . set_title ( options [ ' title ' ] , size = options [ ' sizes ' ] [ ' title ' ] )
##################################################################
############################# LEGEND #############################
##################################################################
if ax . get_legend ( ) :
ax . get_legend ( ) . remove ( )
return fig , ax
def prettify_labels ( label ) :
labels_dict = {
' 2th ' : ' 2$ \\ theta$ ' ,
' I ' : ' Intensity '
}
return labels_dict [ label ]
#def plot_diffractograms():
#def plot_heatmap():
def update_options ( options , required_options , default_options ) :
if not options :
options = default_options
else :
for option in required_options :
if option not in options . keys ( ) :
options [ option ] = default_options [ option ]
return options