在 matplotlib 中通过角度为线条分配颜色

Gui*_*ski 5 python colors matplotlib scatter-plot

我正在寻找一种方法,以响应线条角度的方式为 matplotlib 中的线条图指定颜色。这是我当前的代码:

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
horz = [[0.5,0.6,0.8],[0.1,0.8,0.9],[0.2,0.5,0.9]] 
vert = [[0.1,0.2,0.3],[0.05,0.1,0.15],[0.2,0.3,0.35]]

f = plt.figure(figsize=(6,6))
ax = plt.axes()

for column in range(0,len(horz)):
    x = np.array(horz[column])
    y = np.array(vert[column])
            
    #LINEAR TRENDLINE
    z = np.polyfit(horz[column], vert[column], 1)
    p = np.poly1d(z)
    ax.plot(horz[column],p(horz[column]),"-")
    plt.arrow(x=horz[column][-2],y=p(horz[column])[-2],dx=(horz[column][-1]-horz[column][-2]),dy=(p(horz[column])[-1]-p(horz[column])[-2]), shape='full', lw=.01,
              length_includes_head=True, head_width=.012, head_length=0.02, head_starts_at_zero=False, overhang = 0.5)
            
    #FIG SETTINGS
    plt.xlim([0, 1])
    plt.ylim([0.1,0.5])
    ax.set_title('Title',
             fontsize = 14)
Run Code Online (Sandbox Code Playgroud)

就像现在一样,颜色是随机分配的

这里的想法是,如果线的角度为 0 度,则它将位于给定梯度的一端,如果线的角度为 90 度,则位于另一端。此外,我希望将线条长度视为颜色的强度。因此,如果线条短,它会更接近白色,如果线条长,它会更接近渐变的原始颜色。

Gui*_*ski 1

自己设法解决了。使用非常简单的公式来计算线的斜率和距离,然后将它们用作颜色映射和 Alpha 透明度属性的输入。

import geopandas as gpd
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import cm
import matplotlib.colors as colors
import numpy as np

%matplotlib inline

#Data
horz = [[0.5,0.6,0.8],[0.1,0.3,0.4],[0.2,0.5,0.9],[0.9,0.95,0.95]] 
vert = [[0.1,0.2,0.45],[0.05,0.1,0.15],[0.2,0.3,0.35],[0.1,0.3,0.5]]
            

#Slope calculation
def slopee(x1,y1,x2,y2):
        x = (y2 - y1) / (x2 - x1)
        return x

#Color set up
cmap = plt.cm.coolwarm_r
#0 means a horizontal line, 1 means a line at 45 degrees, infinite means a vertical line (2 is vertical enough)
cNorm  = colors.Normalize(vmin=0, vmax=2)
scalarMap = cm.ScalarMappable(norm=cNorm,cmap=cmap)

#Fig settings
f = plt.figure(figsize=(6,6))
ax = plt.axes()


for column in range(0,len(horz)):
    x = np.array(horz[column])
    y = np.array(vert[column])
    
    #LINEAR TRENDLINE
    # 1   LINEAR
    # >=2 POLINOMIAL
    z = np.polyfit(horz[column], vert[column], 1)
    p = np.poly1d(z)
    
    #Distance calc formula
    def calculateDistance(x1,y1,x2,y2):
        dist = np.sqrt((x2 - x1)**2 + (y2 - y1)**2)
        return dist
    
    #Set up max an min distances
    maxdist = calculateDistance(0,0,0,0.9)
    mindist = calculateDistance(0,0,0,0)
    
    #Calculate line slope
    slope = slopee(horz[column][0],p(horz[column])[0],horz[column][-1],p(horz[column])[-1])
    
    #Not interested in any slopes going "down"
    if slope >=0:
        #Map colors based on slope (0-2)
        colorVal = scalarMap.to_rgba(slope)
        #Map transparency based on distance
        transparency = (calculateDistance(horz[column][0],p(horz[column])[0],horz[column][-1],p(horz[column])[-1])-mindist)/(maxdist-mindist)
        #Set up minimun transparency to be 50% instead of 0%
        transparency = (0.5*transparency) + 0.5
        #The actual arrow plot
        plt.arrow(x=horz[column][0],y=p(horz[column])[0],dx=(horz[column][-1]-horz[column][0]),dy=(p(horz[column])[-1]-p(horz[column])[0]), shape='full',length_includes_head=True, head_starts_at_zero=False, lw=.5, head_width=.011, head_length=0.01, overhang = 0.5, color=colorVal,alpha=transparency)

    #FIG SETTINGS
    plt.xlim([0, 1])
    plt.ylim([0,0.5])
    ax.set_title('Title',fontsize = 14)
Run Code Online (Sandbox Code Playgroud)

色调和强度随坡度和长度而变化