import pandas as pd, numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import matplotlib.patches as mpatches
import matplotlib.ticker as ticker
from matplotlib.lines import Line2D
from mpl_toolkits.axes_grid1 import make_axes_locatable, ImageGrid
from mpl_toolkits.mplot3d.art3d import Line3DCollection
from matplotlib.colors import LinearSegmentedColormap
import mapclassify, pylab, colorsys
pd.set_option("display.precision", 3)
from .utilities import scaling_columnDF
from .colors import rand_cmap, random_colors_list, kindlmann, lighten_color
class Plot():
"""
Class for creating a basic matplotlib plot with a title and customizable settings.
Parameters
----------
figsize: tuple
Tuple of width and height for the figure.
black_background: bool
Whether to set the background color as black.
title: str
Title for the plot.
Attributes
----------
fig: matplotlib.figure.Figure
Figure object for the plot.
ax: matplotlib.axes object
Axes object for the plot.
title: str
Title for the plot.
text_color: str
Color for text elements, white if black_background is True and black otherwise.
font_size_primary: int
Font size for the title.
font_size_secondary: int
Font size for secondary elements.
"""
def __init__(self, figsize, black_background, fontsize, title = None):
self.font_size_primary = fontsize
self.font_size_secondary = fontsize*0.90
self.fig, self.ax = plt.subplots(1, figsize=figsize)
self.title = title
self.ax.axis("equal")
self.black_background = black_background
self.text_color = "white" if black_background else "black"
rect = self.fig.patch
rect.set_facecolor("black" if black_background else "white")
if title is not None:
self.fig.suptitle(title, color = self.text_color, fontsize = self.font_size_primary, fontfamily = 'Times New Roman')
self.fig.tight_layout();
class MultiPlot():
"""
A class for creating multi-plot figures.
Attributes:
----------
figsize: tuple
The size of the figure (width, height) in inches.
nrows: int
The number of rows in the grid layout.
ncols: int
The number of columns in the grid layout.
black_background : bool
Specifies whether the plot has a black background (True) or white background (False).
fontsize: int
The font size to be used in the plot.
title: str or None, optional
The title of the figure. If None, no title is displayed.
"""
def __init__(self, figsize, nrows, ncols, black_background, fontsize, title = None):
"""
Initializes the MultiPlot class.
Parameters
----------
figsize: tuple
The size of the figure (width, height) in inches.
nrows: int
The number of rows in the grid layout.
ncols: int
The number of columns in the grid layout.
black_background : bool
Specifies whether the plot has a black background (True) or white background (False).
fontsize: int
The font size to be used in the plot.
title: str or None
The title of the figure. If None, no title is displayed.
"""
self.ncols = ncols
self.fig, self.grid = plt.subplots(nrows = nrows, ncols = ncols, figsize = figsize)
self.black_background = black_background
self.text_color = "white" if black_background else "black"
rect = self.fig.patch
rect.set_facecolor("black" if black_background else "white")
self.font_size_primary = fontsize
self.font_size_secondary = fontsize*0.90
if title is not None:
self.fig.suptitle(title, color = self.text_color, fontsize = self.font_size_primary, fontfamily = 'Times New Roman',
ha = 'center', va = 'center')
self.fig.tight_layout();
[docs]def plot_gdf(gdf, column = None, title = None, black_background = True, figsize = (15,15), scheme = None, bins = None,
classes = None, norm = None, cmap = None, color = None, alpha = None, geometry_size = 1.0,
geometry_size_column = None, geometry_size_factor = None, legend = False, fontsize = 15, cbar = False, cbar_ticks = 5,
cbar_max_symbol = False, cbar_min_max = False, cbar_shrink = 0.75, axes_frame = False,
base_map_gdf = pd.DataFrame({"a": []}), base_map_color = None, base_map_alpha = 0.4, base_map_geometry_size = 1.1,
base_map_zorder = 0):
"""
It plots the geometries of a single GeoDataFrame, coloring on the bases of the values contained in column, using a given scheme.
When only column is provided (no scheme), a categorical map is depicted.
When no column is provided, a plain map is shown.
The other parameters regulate colorbar, legend, base map.
Use this function for plotting in relation to maximum one column, one GeoDataFrame.
Parameters
----------
gdf: GeoDataFrame
GeoDataFrame to be plotted.
column: str
Column on which the plot is based.
title: str
Title of the plot.
black_background: bool
Specifies whether the plot has a black background (True) or white background (False).
fig_size: float
Size of the figure's side extent.
scheme: str
Classification method. Choose amongst the options listed at https://pysal.org/mapclassify/api.html.
bins: list
Bins defined by the user.
classes: int
Number of classes for categorizing the data when scheme is not "None".
norm: array
A class that specifies a desired data normalization into a [min, max] interval.
cmap: str or matplotlib.colors.LinearSegmentedColormap
Color map for the plot. See matplotlib colormaps for a list of possible values or pass a colormap.
color: str
Categorical color applied to all geometries when not using a column to color them.
alpha: float
Alpha value of the plotted layer.
geometry_size: float
Point size value when plotting a Point GeoDataFrame or Width value when plotting LineString GeoDataFrame.
geometry_size_columns: List of str
The column name in the GeoDataFrame to be used for scaling for manipulating the geometry size.
geometry_size_factor: float
Rescaling factor for the column provided, if any. The column is rescaled from 0 to 1, and the
geometry_size_factor is used to rescale the marker size accordingly
(e.g., rescaled variable's value [0-1] * factor) when plotting a Point GeoDataFrame.
legend: bool
When True, show the legend.
fontsize: int
Font size.
cbar: bool
If True, show the colorbar; otherwise, don't. When True, the legend is not shown.
cbar_ticks: int
Number of ticks along the colorbar.
cbar_max_symbol: bool
If True, show the ">" next to the highest tick's label in the colorbar (useful when normalizing).
cbar_min_max: bool
If True, only show the ">" and "<" as labels of the lowest and highest ticks' the colorbar.
cbar_shrink:
Fraction by which to multiply the size of the colorbar.
axes_frame: bool
If True, show the axes' frame.
base_map_gdf: GeoDataFrame
Additional layer to use as a base map.
base_map_color: str
Color applied to all geometries of the base map.
base_map_alpha: float
Base map's alpha value.
base_map_geometry_size: float
Base map's marker size when the base map is a Point GeoDataFrame.
base_map_zorder: int
Z-order of the layer. If 0, plots first, thus main GeoDataFrame on top; if 1, plots last, thus on top.
Returns
-------
fig: matplotlib.figure.Figure object
the resulting figure
"""
plot = Plot(figsize = figsize, black_background = black_background, title = title, fontsize = fontsize)
fig, ax = plot.fig, plot.ax
ax.set_aspect("equal")
set_axes_frame(axes_frame, ax, black_background, plot.text_color)
zorder = 0
if cbar:
legend = False
if cbar & (norm is None):
min_value = gdf[column].min()
max_value = gdf[column].max()
norm = plt.Normalize(vmin = min_value, vmax = max_value)
if (not base_map_gdf.empty):
plot_baseMap(gdf = base_map_gdf, ax = ax, color = base_map_color, geometry_size = base_map_geometry_size, alpha = base_map_alpha,
zorder = base_map_zorder )
if base_map_zorder == 0:
zorder = 1
if geometry_size_column is None:
geometry_size_column = column
plotOn_ax(ax, gdf, column = column, scheme = scheme, bins = bins, classes = classes, norm = norm, cmap = cmap, color = color, alpha = alpha,
geometry_size = geometry_size, geometry_size_column = geometry_size_column, geometry_size_factor = geometry_size_factor,
zorder = zorder, legend = legend)
if cbar:
generate_colorbar(plot = plot, cmap = cmap, norm = norm, cbar_ticks = cbar_ticks, cbar_max_symbol = cbar_max_symbol, cbar_min_max = cbar_min_max,
cbar_shrink = cbar_shrink)
elif legend:
generate_legend_ax(ax, plot)
return plot.fig
[docs]def plot_grid_gdfs_column(gdfs = [], column = None, ncols = 1, nrows = 1, titles = [], black_background = True, figsize = (15,15), scheme = None, bins = None,
classes = None, norm = None, cmap = None, color = None, alpha = None, geometry_size = None, geometry_size_columns = [], geometry_size_factor = None,
legend = False, fontsize = 15, cbar = False, cbar_ticks = 5, cbar_max_symbol = False, cbar_min_max = False, cbar_shrink = 0.75, axes_frame = False):
"""
It plots the geometries of different GeoDataFrames, coloring on the bases of the values contained in the provided column, using a given scheme.
When only column is provided (no scheme), a categorical map is depicted.
When no column is provided, a plain map is shown.
The other parameters regulate colorbar, legend, etc (no basemap here).
Use this function for plotting in relation to maximum one column, for multiple GeoDataFrames.
Parameters
----------
gdfs: list of GeoDataFrame
The list of GeoDataFrames to be plotted.
column: str
Column on which the plot is based.
ncols: int
The number of desired columns for organising the subplots.
nrows: int
The number of desired rows for organising the subplots.
titles: list of str
The list of titles, one per axes (and column, when provided).
black_background: boolean
Black background or white.
fig_size: float
Size figure extent.
scheme: str
Classification method. Choose amongst the options listed at https://pysal.org/mapclassify/api.html.
bins: list
Bins defined by the user.
classes: int
Number of classes for categorizing the data when scheme is not "None".
norm: array
A class that specifies a desired data normalization into a [min, max] interval.
cmap: str or matplotlib.colors.LinearSegmentedColormap
Color map for the plot. See matplotlib colormaps for a list of possible values or pass a colormap.
color: str
Categorical color applied to all geometries when not using a column to color them.
alpha: float
Alpha value of the plotted layer.
geometry_size: float
Point size value when plotting a Point GeoDataFrame or Width value when plotting LineString GeoDataFrame.
geometry_size_columns: List of str
The column name(s) in the GeoDataFrames to be used for scaling the geometry size.
geometry_size_factor: float
Rescaling factor for the column provided, if any. The column is rescaled from 0 to 1, and the
geometry_size_factor is used to rescale the marker size accordingly
(e.g., rescaled variable's value [0-1] * factor) when plotting a Point GeoDataFrame.
legend: bool
When True, show the legend.
fontsize: int
Font size.
cbar: bool
If True, show the colorbar; otherwise, don't. When True, the legend is not shown.
cbar_ticks: int
Number of ticks along the colorbar.
cbar_max_symbol: bool
If True, show the ">" next to the highest tick's label in the colorbar (useful when normalizing).
cbar_min_max: bool
If True, only show the ">" and "<" as labels of the lowest and highest ticks' the colorbar.
cbar_shrink:
Fraction by which to multiply the size of the colorbar.
axes_frame: bool
If True, show the axes' frame.
Returns
-------
fig: matplotlib.figure.Figure object
the resulting figure
"""
if (len(gdfs)+1 != ncols*nrows) & (len(gdfs) != ncols*nrows):
raise ValueError("Please provide an appropriate combination of nrows and ncols")
multiPlot = MultiPlot(figsize = figsize, nrows = nrows, ncols = ncols, black_background = black_background, fontsize = fontsize)
if (cbar) & (norm is None):
min_value = min([gdf[column].min() for gdf in gdfs])
max_value = max([gdf[column].max() for gdf in gdfs])
norm = plt.Normalize(vmin = min_value, vmax = max_value)
for n, ax in enumerate(multiPlot.grid.flat):
if n > len(gdfs)-1:
ax.set_visible(False)
continue
gdf = gdfs[n]
parameters = {'ax': ax, 'n': n, 'multiPlot': multiPlot, 'column': column , 'gdf': gdf, 'titles': titles,
'scheme': scheme, 'bins': bins, 'classes': classes, 'norm': norm, 'cmap': cmap,
'color': color, 'alpha': alpha, 'legend': legend, 'axes_frame': axes_frame,
'geometry_size': geometry_size, 'geometry_size_columns': geometry_size_columns, 'geometry_size_factor': geometry_size_factor}
subplot(**parameters)
if (cbar) & (not legend):
generate_colorbar(plot = multiPlot, cmap = cmap, norm = norm, cbar_ticks = cbar_ticks, cbar_max_symbol = cbar_max_symbol, cbar_min_max = cbar_min_max,
cbar_shrink = cbar_shrink)
return multiPlot.fig
[docs]def plot_grid_gdf_columns(gdf, columns = [], ncols = 1, nrows = 1, titles = [], black_background = True, figsize = (15,15), scheme = None, bins = None,
classes = None, norm = None, cmap = None, color = None, alpha = None,
geometry_size = None, geometry_size_columns = [], geometry_size_factor = None, legend = False, fontsize = 15,
cbar = False, cbar_ticks = 5, cbar_max_symbol = False, cbar_min_max = False, cbar_shrink = 0.75, axes_frame = False):
"""
It plots the geometries of a GeoDataFrame, coloring on the bases of the values contained in two or more provided columns, using a given scheme.
When no columns are provided, the function raises an error.
The other parameters regulate colorbar, legend, etc (no basemap here).
Use this function for plotting in relation to more than one column, for a single GeoDataFrame.
Parameters
----------
gdf: GeoDataFrame
GeoDataFrame to be plotted.
columns: list of str
The list of column on which the plot is based.
ncols: int
The number of desired columns for organising the subplots.
nrows: int
The number of desired rows for organising the subplots.
titles: list of str
Title of the plot.
black_background: boolean
Black background or white.
fig_size: float
Size figure extent.
scheme: str
Classification method. Choose amongst the options listed at https://pysal.org/mapclassify/api.html.
bins: list
Bins defined by the user.
classes: int
Number of classes for categorizing the data when scheme is not "None".
norm: array
A class that specifies a desired data normalization into a [min, max] interval.
cmap: str or matplotlib.colors.LinearSegmentedColormap
Color map for the plot. See matplotlib colormaps for a list of possible values or pass a colormap.
color: str
Categorical color applied to all geometries when not using a column to color them.
alpha: float
Alpha value of the plotted layer.
geometry_size: float
Point size value when plotting a Point GeoDataFrame or Width value when plotting LineString GeoDataFrame.
geometry_size_columns: List of str
The column name(s) in the GeoDataFrame to be used for scaling the geometry size.
geometry_size_factor: float
Rescaling factor for the column provided, if any. The column is rescaled from 0 to 1, and the
geometry_size_factor is used to rescale the marker size accordingly
(e.g., rescaled variable's value [0-1] * factor) when plotting a Point GeoDataFrame.
legend: bool
When True, show the legend.
fontsize: int
Font size.
cbar: bool
If True, show the colorbar; otherwise, don't. When True, the legend is not shown.
cbar_ticks: int
Number of ticks along the colorbar.
cbar_max_symbol: bool
If True, show the ">" next to the highest tick's label in the colorbar (useful when normalizing).
cbar_min_max: bool
If True, only show the ">" and "<" as labels of the lowest and highest ticks' the colorbar.
cbar_shrink:
Fraction by which to multiply the size of the colorbar.
axes_frame: bool
If True, show the axes' frame.
Returns
-------
fig: matplotlib.figure.Figure object
the resulting figure
"""
if len(columns) == 0:
raise ValueError("Provide a list of columns to plot the geometries on. For a plain plot, use plot_gdf")
if (len(columns)+1 != ncols*nrows) & (len(columns) != ncols*nrows):
raise ValueError("Please provide an appropriate combination of nrows and ncols")
multiPlot = MultiPlot(figsize = figsize, nrows = nrows, ncols = ncols, black_background = black_background, fontsize = fontsize)
if (cbar) & (norm is None):
min_value = min([gdf[column].min() for column in columns])
max_value = max([gdf[column].max() for column in columns])
norm = plt.Normalize(vmin = min_value, vmax = max_value)
for n, ax in enumerate(multiPlot.grid.flat):
if n > len(columns)-1:
ax.set_visible(False)
continue
column = columns[n]
parameters = {'ax': ax, 'n': n, 'multiPlot': multiPlot, 'column': column , 'gdf': gdf, 'titles': titles,
'scheme': scheme, 'bins': bins, 'classes': classes, 'norm': norm, 'cmap': cmap,
'color': color, 'alpha': alpha, 'legend': legend, 'axes_frame': axes_frame,
'geometry_size': geometry_size, 'geometry_size_columns': geometry_size_columns, 'geometry_size_factor': geometry_size_factor}
subplot(**parameters)
if (cbar) & (not legend):
generate_colorbar(plot = multiPlot, cmap = cmap, norm = norm, cbar_ticks = cbar_ticks, cbar_max_symbol = cbar_max_symbol, cbar_min_max = cbar_min_max,
cbar_shrink = cbar_shrink)
return multiPlot.fig
def plotOn_ax(ax, gdf, column = None, scheme = None, bins = None, classes = 7, norm = None, cmap = None, color = 'red', alpha = 1.0,
geometry_size = 1.0, geometry_size_column = None, geometry_size_factor = None, legend = False, zorder = 0):
"""
Parameters
----------
ax: matplotlib.axes object
The axes object on which to create the subplot.
gdf: GeoDataFrame
GeoDataFrame to be plotted.
column: str
Column on which the plot is based.
scheme: str
Classification method. Choose amongst the options listed at https://pysal.org/mapclassify/api.html.
bins: list
Bins defined by the user.
classes: int
Number of classes for categorizing the data when scheme is not "None".
norm: array
A class that specifies a desired data normalization into a [min, max] interval.
cmap: str or matplotlib.colors.LinearSegmentedColormap
Color map for the plot. See matplotlib colormaps for a list of possible values or pass a colormap.
color: str
Categorical color applied to all geometries when not using a column to color them.
alpha: float
Alpha value of the plotted layer.
geometry_size: float
Point size value when plotting a Point GeoDataFrame or Width value when plotting LineString GeoDataFrame.
geometry_size_columns: str
The column name in the GeoDataFrame to be used for scaling the geometry size.
geometry_size_factor: float
Rescaling factor for the column provided, if any. The column is rescaled from 0 to 1, and the
geometry_size_factor is used to rescale the marker size accordingly
(e.g., rescaled variable's value [0-1] * factor) when plotting a Point GeoDataFrame.
legend: bool
When True, show the legend.
zorder: int
Zorder of this layer; e.g. if 0, plots first, thus main GeoDataFrame on top; if 1, plots last, thus on top.
"""
gdf = gdf.copy()
categorical = not (norm is not None) | (scheme is not None)
if not categorical:
color = None
if cmap is None:
cmap = kindlmann()
if norm is not None:
scheme = None
if (gdf[column].dtype != 'O' ):
gdf = gdf.reindex(gdf[column].abs().sort_values(ascending = True).index)
else:
gdf[column] = gdf[column].astype(float)
elif (column is not None) & (cmap is None):
cmap = rand_cmap(len(gdf[column].unique()))
if len(gdf[column].unique()) == 1:
legend = False
cmap = None
color = 'red'
c_k = dict(k=classes) if bins is None else dict(bins=bins, k=len(bins))
scheme = 'User_Defined' if bins is not None else scheme
parameters = {'ax': ax, 'column': column, 'classification_kwds': c_k, 'scheme': scheme, 'norm': norm,
'cmap': cmap, 'categorical': categorical, 'color': color, 'alpha': alpha, 'legend': legend,
'zorder': zorder}
geometry_type = gdf.iloc[0].geometry.geom_type
if geometry_type == 'Point':
if (geometry_size_factor is not None):
gdf[column+'_sc'] = scaling_columnDF(gdf[column])
geometry_size = np.where(gdf[column+'_sc'] >= 0.20, gdf[column+'_sc']*geometry_size_factor, 0.40) # marker size
parameters['markersize'] = geometry_size
elif geometry_type == 'LineString':
if geometry_size_factor is not None:
geometry_size = [(abs(value)*geometry_size_factor) if (abs(value)*geometry_size_factor) > 1.1 else 1.1 for value in
gdf[column]]
sub_parameters = {'linewidth': geometry_size, 'capstyle': 'round', 'joinstyle':'round'}
parameters.update(sub_parameters)
else:
parameters['edgecolor'] = 'none'
gdf.plot(**parameters)
def subplot(ax, n, multiPlot, gdf, column, titles, scheme, bins, classes, norm, cmap, color, alpha, geometry_size, geometry_size_columns,
geometry_size_factor, legend, axes_frame):
"""
Create a subplot with a map plot on the given axes.
Parameters
----------
ax: matplotlib.axes object
The axes object on which to create the subplot.
n: int
The index of the subplot.
multiPlot: MultiPlot object
The MultiPlot object controlling the plot settings.
gdf: GeoDataFrame
The GeoDataFrame containing the data to plot.
column: str
The column name in the GeoDataFrame to be used for plotting.
titles: str or sequence
The title(s) of the subplot(s).
scheme: str
The classification scheme to use for mapping the data.
bins: int or sequence or pandas.IntervalIndex
The number of bins to use for the classification or the bin intervals.
classes: int or sequence
The number of classes to use for the classification or the class intervals.
geometry_size: float
Marker size value when plotting a Point GeoDataFrame or line width value when plotting LineString GeoDataFrame.
geometry_size_columns: List of str
The column name(s) in the GeoDataFrame to be used for scaling the geometry size.
geometry_size_factor: float
The factor by which to scale the geometry size.
norm: Normalize or str
The normalization scheme to use for mapping values to colors.
cmap: str or Colormap
The colormap to use for mapping values to colors.
color: str
Categorical color applied to all geometries when not using a column to color them.
alpha: float
Alpha value of the plotted layer.
legend: bool
If True, show the legend; otherwise, don't.
axes_frame: bool
Flag indicating whether to draw axes frame or not.
"""
ax.set_aspect("equal")
set_axes_frame(axes_frame, ax, multiPlot.black_background, multiPlot.text_color)
if titles:
ax.set_title(titles[n], loc='center', fontfamily = 'Times New Roman', fontsize = multiPlot.font_size_primary, color = multiPlot.text_color,
pad = 15)
geometry_size_column = column
if geometry_size_columns:
geometry_size_column = geometry_size_columns[n]
legend_ax = False
legend_fig = False
if legend:
legend_ax = (n == 1 and scheme == 'User_Defined') or (scheme != 'User_Defined')
legend_fig = (n == 1 and scheme == 'User_Defined')
plotOn_ax(ax, gdf, column = column, scheme = scheme, bins = bins, classes = classes, norm = norm, cmap = cmap, color = color,
alpha = alpha, legend = legend_ax, geometry_size = geometry_size, geometry_size_column = geometry_size_column,
geometry_size_factor = geometry_size_factor)
if legend_fig:
generate_legend_fig(ax, multiPlot)
elif legend_ax:
generate_legend_ax(ax, multiPlot)
def plot_baseMap(gdf = None, ax = None, color = None, geometry_size = None, alpha = 0.5, zorder = 0):
"""
It plots the geometries of a GeoDataFrame, coloring on the basis of the values contained in the provided columns, using a given scheme.
If only column is provided, a categorical map is depicted.
If no column is provided, a plain map is shown.
Parameters
----------
gdf: GeoDataFrame
The GeoDataFrame containing the map data.
ax: matplotlib.axes object
The axes object on which to create the subplot.
color: str
The color to use for mapping
geometry_size: float
Point size value when plotting a Point GeoDataFrame or Width value when plotting LineString GeoDataFrame.
alpha: float
Alpha value of the plotted layer.
zorder: str
The order of the map elements with respect to other elements in the axis, default value is 0.
"""
if gdf.iloc[0].geometry.geom_type == 'LineString':
gdf.plot(ax = ax, color = color, linewidth = geometry_size, alpha = alpha,zorder = zorder)
if gdf.iloc[0].geometry.geom_type == 'Point':
gdf.plot(ax = ax, color = color, markersize = geometry_size, alpha = alpha, zorder = zorder)
if gdf.iloc[0].geometry.geom_type == 'Polygon':
gdf.plot(ax = ax, color = color, alpha = alpha, zorder = zorder)
def generate_legend_fig(ax, plot):
"""
It generates the legend for an entire figure.
Parameters
----------
ax: matplotlib.axes object
The axes object on which to create the subplot.
plot: Plot, MultiPlot Object
The Plot object.
"""
leg = ax.get_legend()
fig_leg = plot.fig.legend(handles = leg.legend_handles, labels = [t.get_text() for t in leg.texts], loc=5,
borderaxespad= 0)
ax.get_legend().remove()
plt.setp(fig_leg.texts, family='Times New Roman', fontsize = plot.font_size_secondary, color = plot.text_color,
va = 'center')
fig_leg.get_frame().set_linewidth(0.0) # remove legend border
fig_leg.set_zorder(102)
fig_leg.get_frame().set_facecolor('none')
for handle in fig_leg.legend_handles:
if not isinstance(handle, Line2D):
handle._legmarker.set_markersize(15)
else:
break
def generate_legend_ax(ax, plot):
"""
It generate the legend for an axes.
Parameters
----------
ax: matplotlib.axes object
The axes object on which to create the subplot.
plot: Plot, MultiPlot Object
The Plot object.
"""
leg = ax.get_legend()
plt.setp(leg.texts, family='Times New Roman', fontsize = plot.font_size_secondary, color = plot.text_color, va = 'center')
bbox_legend = leg.get_window_extent()
bbox_axes = ax.get_window_extent()
legend_height = bbox_legend.y1 - bbox_legend.y0
axes_height = bbox_axes.y1 - bbox_axes.y0
vertical_position = 0.5+(legend_height/2/axes_height)
leg.set_bbox_to_anchor((1.0, vertical_position))
leg.get_frame().set_linewidth(0.0) # remove legend border
leg.set_zorder(102)
for handle in leg.legend_handles:
if not isinstance(handle, Line2D):
handle._legmarker.set_markersize(12)
else:
break
leg.get_frame().set_facecolor('none')
def generate_colorbar(plot = None, cmap = None, norm = None, cbar_ticks = 5, cbar_max_symbol = False, cbar_min_max = False, cbar_shrink = 0.95):
"""
It plots a colorbar, given some settings.
Parameters
----------
plot: Plot, MultiPlot Object
The Plot object.
cmap: str or matplotlib.colors.LinearSegmentedColormap
Color map for the plot. See matplotlib colormaps for a list of possible values or pass a colormap.
norm: array
A class that specifies a desired data normalisation into a [min, max] interval.
cbar_ticks: int
Number of ticks along the colorbar.
cbar_max_symbol: bool
If True, show the ">" next to the highest tick's label in the colorbar (useful when normalizing).
cbar_min_max: bool
If True, only show the ">" and "<" as labels of the lowest and highest ticks' the colorbar.
cbar_shrink:
Fraction by which to multiply the size of the colorbar.
"""
if isinstance(plot, Plot):
ax = plot.ax
else:
ax = plot.grid
cb = plot.fig.colorbar(cm.ScalarMappable(norm=norm, cmap=cmap), ax = ax, shrink = cbar_shrink)
tick_locator = ticker.MaxNLocator(nbins=cbar_ticks)
cb.locator = tick_locator
cb.update_ticks()
cb.outline.set_visible(False)
ticks = list(cb.get_ticks())
for t in ticks:
if (t == ticks[-1]) & (t != norm.vmax) :
ticks[-1] = norm.vmax
if cbar_min_max:
ticks = [norm.vmin, norm.vmax]
cb.set_ticks(ticks)
cb.ax.set_yticklabels([round(t,1) for t in ticks])
if cbar_max_symbol:
cb.ax.set_yticklabels([round(t,1) if t < norm.vmax else "> "+str(round(t,1)) for t in cb.ax.get_yticks()])
plt.setp(plt.getp(cb.ax, "yticklabels"), color = plot.text_color, fontfamily = 'Times New Roman', fontsize= plot.font_size_secondary)
def set_axes_frame(axes_frame = False, ax = None, black_background = False, text_color = 'black'):
"""
It draws the axis frame.
Parameters
----------
axes_frame: bool
Flag indicating whether to draw axes frame or not.
ax: matplotlib.axes object
The axes object on which to create the subplot.
black_background: boolean
It indicates whether the background color is black.
text_color: str
The text color.
"""
if not axes_frame:
ax.set_axis_off()
return
ax.xaxis.set_ticklabels([])
ax.yaxis.set_ticklabels([])
ax.tick_params(axis= 'both', which= 'both', length=0)
for spine in ax.spines:
ax.spines[spine].set_color(text_color)
if black_background:
ax.set_facecolor('black')