How to change colors automatically once a parameter is changed

后端 未结 1 618
小蘑菇
小蘑菇 2020-12-11 22:11

In the following code, the color of bars changes as the threshold is changed. Instead of using the threshold and plotting the horizontal line in the code, I want to use the

相关标签:
1条回答
  • 2020-12-11 22:52

    First you should use exactly one bar plot and exactly one axhline (using more will make everything chaotic). You can set the colors of the bars via

    for bar in bars:
        bar.set_color(..)
    

    and you can update the axhline's position via line.set_ydata(position).

    Now, for every mouse move event you need to update the axhline's position, calculate the percentages and apply a new colors to the bars. So those things should be done in a function, which is called every time the mouse move event is triggered. After those settings have been applied the canvas needs to be drawn for them to become visible.

    Here is a complete code.

    import pandas as pd
    import numpy as np
    import matplotlib.colors as mcol
    import matplotlib.cm as cm
    import matplotlib.pyplot as plt
    
    np.random.seed(12345)
    df = pd.DataFrame([np.random.normal(335,1500,300), 
                       np.random.normal(410,900,300), 
                       np.random.normal(410,1200,300), 
                       np.random.normal(480,550,300)], 
                      index=[1,2,3,4])
    
    fig, ax = plt.subplots()
    
    threshold=420.
    bars = plt.bar(range(df.shape[0]), df.mean(axis = 1), color = 'lightslategrey')
    axline = plt.axhline(y = threshold, color = 'grey', alpha = 0.5)
    
    cm1 = mcol.LinearSegmentedColormap.from_list("Test",["b", "white", "purple"])
    cpick = cm.ScalarMappable(cmap=cm1) 
    cpick.set_array([])
    plt.colorbar(cpick, orientation='horizontal')
    
    def percentages(threshold):
        percentages = []
        for bar in bars:
            percentage = (bar.get_height()-threshold)/bar.get_height()
            if percentage>1: percentage = 1
            if percentage<0: percentage=0
            percentages.append(percentage)
        return percentages
    
    def update(threshold):
        axline.set_ydata(threshold)
        perc = percentages(threshold)
        for bar, p in zip(bars, perc):
            bar.set_color(cpick.to_rgba(p))
    
    # update once before showing
    update(threshold)
    
    def onMouseMove(event):
        if event.inaxes == ax:
            update(event.ydata)
            fig.canvas.draw_idle()
    
    fig.canvas.mpl_connect('motion_notify_event', onMouseMove)
    
    plt.xticks(range(df.shape[0]), df.index, alpha = 0.8)
    
    plt.show()
    
    0 讨论(0)
提交回复
热议问题