.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/30-showcase-cyberpunk.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_30-showcase-cyberpunk.py: ==================== ANother cybepunk example ==================== .. GENERATED FROM PYTHON SOURCE LINES 7-254 .. image-sg:: /examples/images/sphx_glr_30-showcase-cyberpunk_001.png :alt: Diamonds :srcset: /examples/images/sphx_glr_30-showcase-cyberpunk_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none /home/docs/checkouts/readthedocs.org/user_builds/mpl-visual-context/checkouts/improve-documentation/examples/30-showcase-cyberpunk.py:33: FutureWarning: The default of observed=False is deprecated and will be changed to True in a future version of pandas. Pass observed=False to retain current behavior or observed=True to adopt the future default and silence this warning. g = diamonds.groupby("cut") | .. code-block:: Python #* Import things import seaborn as sns import matplotlib as mpl import matplotlib.pyplot as plt from mpl_visual_context.patheffects_color import StrokeColorFromFillColor #* use mplcyberpunk for background and colorsets import mplcyberpunk plt.style.use("cyberpunk") #* load diamonds datasets diamonds = sns.load_dataset("diamonds") #* Plot fig, ax = plt.subplots(figsize=(7, 5), num=1, clear=True, layout="constrained") sns.despine(fig) import numpy as np bins = np.logspace(2.5, 4.3, 20) g = diamonds.groupby("cut") cut_names = ['Fair', 'Good', 'Very Good', 'Premium', 'Ideal'] bottom = np.zeros(len(bins)-1, dtype="i") hh = [] for i, cut in enumerate(cut_names): g1 = g.get_group(cut) cnt, edges = np.histogram(g1["price"], bins=bins) hh.append((cut, cnt, edges, bottom)) bottom = bottom + cnt # We are using stairs command. for cut, cnt, edges, bottom in hh[::-1]: sp = ax.stairs(bottom+cnt, edges, baseline=bottom, fill=True, label=cut) ax.set(xlabel="Price", ylabel="Counts") ax.set_xscale("log") ax.xaxis.set_major_formatter(mpl.ticker.ScalarFormatter()) ax.set_xticks([500, 1000, 2000, 5000, 10000]) ax.legend() ax.set_title("Diamonds", size=60) #* Lets give it some taste of patheffects. We import necessary modules. import mpl_visual_context.patheffects as pe import mpl_visual_context.image_box as ib import mpl_visual_context.image_effect as ie from mpl_visual_context.patheffects_color import BlendAlpha from mpl_visual_context.patheffects_multicolor import MultiColorLine #* We define a custom PathEffects from matplotlib.patheffects import PathEffectRenderer from mpl_visual_context.patheffects_base import ChainablePathEffect class RendererSetPatheffects(ChainablePathEffect): def __init__(self, pel): self._pel = pel def _convert(self, renderer, gc, tpath, affine, rgbFace=None): renderer = PathEffectRenderer(self._pel, renderer) return renderer, gc, tpath, affine, rgbFace #* Let's make the stairs have round corners round_corner = pe.RoundCorner(10) for p in ax.patches: p.set_path_effects([round_corner]) #* Add alpha gradient alpha_gradient = pe.AlphaGradient("0 ^ 0.3") for p in ax.patches: # The alpha value starts from 0 at the bottom and increase upward to be 0.5 at the top. p.set_path_effects([round_corner | alpha_gradient]) #* Add multicolor line # the path were created using fill_between and has both upper and lower # boundary. For the stroke, we only want to stroke its upper boundary, which is the 1st # half of the path. first_half = pe.Partial(0, 0.5) # The line is not being stroked because its linewidth and alpha set to 0. So we # override this and make the line thicker. gc_for_stroke = pe.GCModify(linewidth=4, alpha=1) for p in ax.patches: # For the ultiColorLine patheffects, we need to manually create an imagebox # and provide it to the patheffects. The MultiColorLine patheffect will # segment the path into small pieces and assign colors using the color from # the imagebox at the position of the path segment. ib_line = ib.ColorBox(p.get_fc(), alpha="up", coords=p, axes=ax) multi_color_line = MultiColorLine(ib_line, min_length=5) p.set_path_effects([ ( first_half | round_corner | gc_for_stroke | multi_color_line ) ]) #* Add multicolor line # The above result is not ideal as it shows some artefacts where segments of # different colors meet. MultiColorLine temporarily override capstyle to round, # otherwise caps between segments can be bisible. This is not good if alpha is # not 1 as overrapping area look brighter than other parts. There is no good # solution for this. One workaround is to blend the color of line segments with # background color which reset alpha to 1. # pick up the color of background. This color will be used for alpha blending. bg = ax.patch.get_fc() # We want to blend bg for the results MultiColorLine. However, MultiColorLine # patheffects, which draws multiple lines, is not further chainable. It # terminates the chain. Behind the scene, MultiColorLine calss # renderer.draw_path multiple times for each line segment. So, we need to # override the renderer itself so that have its own patheffects (of alpha # blending). renderer_set_alpha_blend = RendererSetPatheffects([BlendAlpha(bg)]) for p in ax.patches: ib_line = ib.ColorBox(p.get_fc(), alpha="up", coords=p, axes=ax) multi_color_line = MultiColorLine(ib_line, min_length=5) p.set_path_effects([ ( first_half | round_corner | gc_for_stroke | renderer_set_alpha_blend | multi_color_line ) ]) #* Now, we will make this line glow. # For the glow effect, we will use image effect. ImageEffect create an image by # draing the artist using the agg backend, and apply effects on that image, # such as GaussianBlur. glow = pe.ImageEffect(ie.Pad(20) # we pad the image so that it has enough space for blur. # First, we gaussian blur the alpha channel. | ie.GaussianBlur(10, channel_slice=slice(3, 4)) # GaussianBlur decreases peak alpha value, we increase # the overall alpha by facot of 2. | ie.AlphaAxb((2, 0)) # We also expand the rgb channel. The background # have color of white (1, 1, 1). Thus we apply Erosion # effect (which uses scipy's gray_erosion behind the # scene) to expand the colored region. | ie.Erosion(40, channel_slice=slice(0, 3)) ) # As the line will be gaussian smoothed, doing alpha_blending does not affect # our results. We simply remove it from the chain. for p in ax.patches: ib_line = ib.ColorBox(p.get_fc(), alpha="up", coords=p, axes=ax) multi_color_line = MultiColorLine(ib_line, min_length=5) p.set_path_effects([ ( first_half | round_corner | gc_for_stroke | multi_color_line | glow ) ]) #* combine them all # In addition to the glowed line, we fill the path as we did and also we # stroke the original multi_color_line. for p in ax.patches: ib_line = ib.ColorBox(p.get_fc(), alpha="up", coords=p, axes=ax) multi_color_line = MultiColorLine(ib_line, min_length=5) p.set_path_effects([ ( first_half | round_corner | gc_for_stroke | multi_color_line | glow ), (round_corner | alpha_gradient), ( first_half | round_corner | gc_for_stroke | renderer_set_alpha_blend | multi_color_line ) ]) #* Let apply similar effects to the title # we create color gradient image using the default colomap with its value # varies from 0 at the left and 1 at the right. color_gradient_box = ib.ImageBox("right", coords=ax.title, axes=ax) ax.title.set_path_effects([ ( pe.GCModify(linewidth=2, alpha=1) | MultiColorLine(color_gradient_box, min_length=5) | glow ), ( pe.FillImage(color_gradient_box, alpha=0.5) ), ( pe.GCModify(linewidth=2, alpha=1) | MultiColorLine(color_gradient_box, min_length=5) ) ]) fig.get_layout_engine().set(w_pad=16 / 72, h_pad=16 / 72) plt.show() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.943 seconds) .. _sphx_glr_download_examples_30-showcase-cyberpunk.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: 30-showcase-cyberpunk.ipynb <30-showcase-cyberpunk.ipynb>` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: 30-showcase-cyberpunk.py <30-showcase-cyberpunk.py>` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: 30-showcase-cyberpunk.zip <30-showcase-cyberpunk.zip>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_