Giter Club home page Giter Club logo

Comments (5)

IshanJ25 avatar IshanJ25 commented on May 21, 2024

What I mean to say Is that I want to have this sort of plot using your theme:
image

How can I possibly achieve this setting?

edit: another example:
image

from mplcyberpunk.

dhaitz avatar dhaitz commented on May 21, 2024

as a workaround, can you try plotting the positive and negative parts separately with different colors?

from mplcyberpunk.

IshanJ25 avatar IshanJ25 commented on May 21, 2024

I have been trying to get amount the function and tweak it to fulfil the requirement.

Since I need only the line color and gradient, I removed all other functions to make it more straightforward on my local machine.

Here is the code (core.py) that works for me:

from itertools import groupby
import numpy as np
from matplotlib.lines import Line2D
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
from matplotlib.patches import Polygon


def add_glow_effects(color_positive: str = '#0000ff',
                     color_negative: str = '#ff0000',
                     alpha_gradientglow: float = 1.0):
    add_gradient_fill(alpha_gradientglow, color_positive, color_negative, )
    change_line_color(color_positive, color_negative)


def change_line_color(color_positive: str = '#0000ff',
                      color_negative: str = '#ff0000'):
    ax = plt.gca()
    lines = ax.get_lines()

    for line_element in lines:

        if not isinstance(line_element, Line2D):
            continue

        x, y = line_element.get_data(orig=False)
        x, y = optimize_lines(list(x), list(y))
        lines_list = list_form(x, y)

        for line in lines_list:

            y_avg = sum(line[1]) / len(line[1])
            if y_avg >= 0:
                color = color_positive
            else:
                color = color_negative

            line = Line2D(line[0], line[1], linewidth=line_element.get_linewidth(), color=color)

            data = list(line.get_data(orig=False))
            linewidth = line.get_linewidth()

            ax.plot(data[0], data[1], linewidth=linewidth, color=color)


# noinspection PyArgumentList
def add_gradient_fill(alpha_gradientglow: float = 1.0,
                      color_positive: str = '#00ff00',
                      color_negative: str = '#ff0000'):
    """Add a gradient fill under each line,
       i.e. faintly color the area below the line."""

    ax = plt.gca()
    lines = ax.get_lines()

    for line_element in lines:

        if not isinstance(line_element, Line2D):
            continue

        x, y = line_element.get_data(orig=False)
        alpha = line_element.get_alpha()
        alpha = 1.0 if alpha is None else alpha
        x, y = optimize_lines(list(x), list(y))
        lines_list = list_form(x, y)

        # get max from every second list of every list in this list
        y_values = []
        for i in lines_list:
            for j in i[1]:
                y_values.append(j)
        # y_max_global = max(y_values)
        # y_min_global = min(y_values)
        del y_values

        for line in lines_list:

            y_avg = sum(line[1]) / len(line[1])

            # don't add gradient fill for glow effect lines:
            if hasattr(line, 'is_glow_line') and line.is_glow_line:
                continue

            line = Line2D(line[0], line[1], linewidth=line_element.get_linewidth())

            zorder = line.get_zorder()

            x, y = line.get_data(orig=False)
            x, y = np.array(x), np.array(y)  # enforce x,y as numpy arrays

            xmin, xmax = x.min(), x.max()
            ymin, ymax = y.min(), y.max()
            xy = np.column_stack([x, y])

            if y_avg >= 0:
                # if ymax == y_max_global:
                #     pass
                # else:
                #     alpha *= (ymax/y_max_global)
                fill_color = color_positive
                linspace = np.linspace(0, alpha, 100)[:, None]
                xy = np.vstack([[xmin, ymin], xy, [xmax, ymin], [xmin, ymin]])
            else:
                # if ymin == y_min_global:
                #     pass
                # else:
                #     alpha *= (ymin/y_min_global)
                fill_color = color_negative
                linspace = np.linspace(alpha, 0, 100)[:, None]
                xy = np.vstack([[xmin, ymax], xy, [xmax, ymax], [xmin, ymax]])

            rgb = mcolors.colorConverter.to_rgb(fill_color)
            z = np.empty((100, 1, 4), dtype=float)
            z[:, :, :3] = rgb
            z[:, :, -1] = linspace

            im = ax.imshow(z, aspect='auto',
                           extent=[xmin, xmax, ymin, ymax],
                           alpha=alpha_gradientglow,
                           origin='lower', zorder=zorder)
            clip_path = Polygon(xy, facecolor='none', edgecolor='none', closed=True)
            ax.add_patch(clip_path)
            im.set_clip_path(clip_path)
            ax.autoscale(True)


def optimize_lines(x: list, y: list):
    y = [list(element) for index, element in groupby(y, lambda a: a >= 0)]

    indexes = [0]
    for i in y:
        indexes.append(len(i) + indexes[-1])

    # from https://www.geeksforgeeks.org/python-group-consecutive-elements-by-sign/
    x = [x[indexes[i]:indexes[i + 1]] for i, _ in enumerate(indexes) if i != len(indexes) - 1]

    for i in range(len(y) - 1):

        if y[i][-1] == 0 and y[i + 1][0] == 0:
            continue

        a = y[i][-1]
        b = y[i + 1][0]
        diff = abs(a) + abs(b)
        a_ = (abs(0 - a)) / diff
        b_ = abs(0 - b) / diff

        x[i].append(x[i][-1] + a_)
        x[i + 1].insert(0, x[i + 1][0] - b_)

        y[i].append(0)
        y[i + 1].insert(0, 0)

    x = [list(i) for i in x]
    y = [list(i) for i in y]

    # input: x=[1,2,3,4,5], y=[1,2,-5,0,2]
    # output: x=[[1, 2, 2.2857142857142856], [2.2857142857142856, 3, 4.0], [4.0, 4, 5]],
    #         y=[[1, 2, 0], [0, -5, 0], [0, 0, 2]]

    return list(x), list(y)


def list_form(x: list[list], y: list[list]):
    lst = []
    for i in range(len(x)):
        lst.append([x[i], y[i]])
    return lst

Here I have edited the parameters to include positive_color and negative_color, so it gives me an output like this for my specified hex codes:

image

from mplcyberpunk.

IshanJ25 avatar IshanJ25 commented on May 21, 2024

However what i wanted has been achieved, I shared this code so that it could be incorporated in this repository.

Please add me as a contributor if you decide to add this feature, thanks.

from mplcyberpunk.

mayurankv avatar mayurankv commented on May 21, 2024

I would also love this feature! If this was added to the repository, that would be great in my opinion!

from mplcyberpunk.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.