.. _cartoplot: Cartographic Plots ================== This guide uses the example system loaded in :ref:`vizexamplesys`. Please load the example system before following the rest of the tutorial. Introduction ------------ ProteoTwirl calculates angle-dependent properties. This means we have a set of angles indicating where a protein is "viewed" from, and an associated value for each angle. To plot this, we have to map all angles, which can be seen as points on a sphere, to a flat plane. This is impossible to do without distortion (see `Gauss's Theorema Egregium `_). However, many approximate methods with different trade-offs have been developed in cartography to create maps of the Earth. We can reuse these `cartographic projections `_ to plot our angle-dependent properties. In practice, ProteoTwirl uses `CartoPy `_ to create projections. A list of projections available in `CartoPy `_ can be found `here `_. Quick Plots ----------- The easiest way to create a cartographic plot for a given property is to use the ``plot_property`` function. This function will create a contour plot of the property requested, with interpolation between the data points. The function also creates a scatter plot on top with the original data points, with point size indicating value. .. code-block:: python :caption: Property Plot import cartopy.crs as ccrs fig, ax = protein_structure.plot_property( property ="mean_Hydropathy", # name of property cmap ="RdPu", # matplotlib colormap projection = ccrs.Stereographic(), # projection scatter_size =(1,150), # size of scatter plot interp_degre = 16, # how many points to interpolate scatter_col = "#222222", # scatter-plot point color levels = 16 # number of contour levels ) .. figure:: ../../_static/Guides/Visualization/8JXW_Hydropathy.png :figclass: code-output :width: 80% :align: center A quick plot showing how a shape looks at different angles can also be made using ``plot_shape`` as shown below. .. code-block:: python :caption: Shape Plot fig, ax = protein_structure.plot_shape( shape_property = "Alpha_Shape_45_HF20", projection = ccrs.EckertIII(), shape_color = "#ffaaaa", shape_size = 50, figsize = (13,8) ) # Setting a background color, so plot is visible on dark and light mode # of documentation ax.patch.set_facecolor("#14181e") .. figure:: ../../_static/Guides/Visualization/8JXW_Alpha_Shape.png :figclass: code-output :width: 80% :align: center Contour Plots ------------- Cartographic contour plots can be made using the ``plot_carto_contour`` function. You must provide arrays of :math:`\phi` and :math:`\theta` angles, together with an array of values. Here, we will get the angles and values via the ``get_property`` function, as shown below. .. code-block:: python :caption: Get Property & Angles value,angles = protein_structure.get_property( property_name = "mean_Hydropathy", return_angle = True )["mean_Hydropathy"] # value is a list of items, in this case floating-point values print(len(value)) >>> 64 # angles is a numpy array of phi and theta pairs. print(angles.shape) >>> (64, 2) These can then be plotted using the ``plot_carto_contour`` function, as shown below. .. code-block:: python :caption: Plotting using plot_carto_contour from ProteoTwirl.Visualization.CatographyPlot import plot_carto_contour ax = plot_carto_contour( angles = angles, # angle values = value, # values/height projection = ccrs.EckertI(), # projection to use cmap = "plasma", # matplotlib colormap figsize = (13,13), # figure size # gridline can be true/false or a dict with gridline keyword-arguments gridlines = { "colors" : "#ffffff" }, # contour_labels can be true/false or a dict with contour label keyword-arguments contour_labels = { "colors" : "#ffffff", "fmt" : "{:.2f} ".format, }, # contour_lines can be true/false or a dict with contour line keyword-arguments contour_lines={ "colors" : "#dddddd", "linewidths" : 0.6, "linestyles" :"dashed" } ) .. figure:: ../../_static/Guides/Visualization/8JXW_Hydropathy_contour.png :figclass: code-output :width: 100% :align: center It is also possible to use categorical values when creating contour plots. .. code-block:: python :caption: Plotting using plot_carto_contour from ProteoTwirl.Visualization.CatographyPlot import plot_carto_contour value,angles = protein_structure.get_property( property_name = "mean_Hydropathy", return_angle = True )["mean_Hydropathy"] # Convert to categorical categorical_values = ["High" if v > 0.7 else "Medium" if v > 0.6 else "Low" for v in value] ax = plot_carto_contour( angles = angles, values = categorical_values, projection = ccrs.EckertI(), categorical = True, figsize = (13,6), category_colors = {"High": "#FFaaaa", "Medium": "#aaFFaa", "Low": "#aaaaFF"} ) .. figure:: ../../_static/Guides/Visualization/8JXW_Hydropathy_contour_categorical.png :figclass: code-output :width: 100% :align: center Scatter Plots ------------- You can alternatively make a scatter plot of the different angles for a given property using ``plot_carto_scatter``. ``plot_carto_scatter`` also allows scaling and coloring of the scatter points according to a value, such as the ``"mean_Hydropathy"`` also used for contour plots. .. code-block:: python :caption: Plotting using plot_carto_scatter from ProteoTwirl.Visualization.CatographyPlot import plot_carto_scatter ax = plot_carto_scatter( angles = angles, # angle # If string, will color all by same color, but if list of values # will color according to the colormap in cmap color = value, # If single value will use that for all, if array of value will scale # all sizes to the range of sizes in smin_max_plot, according to their value size = value, projection = ccrs.EckertIII(), # projection to use cmap = "viridis", # matplotlib colormap figsize = (13,6), # figure size smin_max_plot = (10,1500), # set min and max marker size # gridline can be true/false or a dict with gridline keyword-arguments gridlines = { "colors" : "#ffffff", "linewidth" : 1.5, }, ) # Setting a background color, so plot is visible on dark and light mode # of documentation ax.patch.set_facecolor("#14181e") .. figure:: ../../_static/Guides/Visualization/8JXW_Hydropathy_scatter.png :figclass: code-output :width: 100% :align: center Shape-Scatter Plots ------------------- The cartographic scatter plot also allows you to use custom shapes as the marker style on the plot. This, for example, allows us to make a plot showing how the protein looks at different angles. We can combine this with the hydropathy values from before since they are present in the same angle space (matching the same set of angles). We confirm this by using: .. code-block:: python :caption: Checking angle-space hydropathy_angle_space = protein_structure.get_angle_space_of_property("mean_Hydropathy") alpha_shape_angle_space = protein_structure.get_angle_space_of_property("Alpha_Shape_45_HF20") print(hydropathy_angle_space == alpha_shape_angle_space) >>> True We can then plot the shape of the protein, and color it according to the mean hydropathy index of exposed residues from that angle. .. code-block:: python :caption: Plotting Shapes by Angle shape,angles = protein_structure.get_property( property_name = "Alpha_Shape_45_HF20", return_angle = True )["Alpha_Shape_45_HF20"] value,_ = protein_structure.get_property( property_name = "mean_Hydropathy", return_angle = True )["mean_Hydropathy"] ax = plot_carto_scatter( angles = angles, # angle color = value, size = 50, marker = shape, projection = ccrs.EckertIII(), # projection to use cmap = "viridis", # matplotlib colormap figsize = (13,7), # figure size # gridline can be true/false or a dict with gridline keyword-arguments gridlines = { "colors" : "#ffffff", "linewidth" : 1.5, }, ) .. figure:: ../../_static/Guides/Visualization/8JXW_Hydropathy_scatter_shape.png :figclass: code-output :width: 100% :align: center When plotting shapes, there are two additional options to keep in mind for how the shapes are rendered. The first of these is ``shape_size``, which determines the resolution at which the shapes are rendered. Below is an example of low-resolution rendering (using ``shape_size = 8`` and ``size = 40``, but otherwise the same settings as above). .. figure:: ../../_static/Guides/Visualization/8JXW_Hydropathy_scatter_shape_low_res.png :figclass: code-output :width: 100% :align: center The other is ``scale_shape``. If ``True``, this will scale the shapes to their correct relative sizes, allowing better comparison of the size of the protein at different angles. On the other hand, this can make some angles hard to see if they are small, and it precludes scaling the shapes according to some value. Below is an example of a very elongated protein (``5BU5``) where ``scale_shape`` is either turned on or off, highlighting that when it is turned on it can be hard to see some smaller shapes. The top plot uses ``scale_shape = False``, and the bottom plot uses ``scale_shape = True``. .. figure:: ../../_static/Guides/Visualization/5BU5_scale_False.png :figclass: code-output :width: 100% :align: center .. figure:: ../../_static/Guides/Visualization/5BU5_scale_True.png :figclass: code-output :width: 100% :align: center Note on Central Longitude ------------------------- Note that if you change the ``central_longitude`` in a projection, then you need to specify that value as ``central_longitude`` in the function you are using (``plot_property``, ``plot_shape``, ``plot_carto_contour``, or ``plot_carto_scatter``).