简体   繁体   English

绘制和对多个y轴进行颜色编码

[英]Plotting and color coding multiple y-axes

This is my first attempt using Matplotlib and I am in need of some guidance. 这是我第一次使用Matplotlib,并且需要一些指导。 I am trying to generate plot with 4 y-axes, two on the left and two on the right with shared x axis. 我正在尝试生成具有4个y轴的图,其中两个在左侧,两个在右侧,并且共享x轴。 Here's my dataset on shared dropbox folder 这是我在共享保管箱文件夹上的数据集

import pandas as pd
%matplotlib inline

url ='http://dropproxy.com/f/D34'

df= pd.read_csv(url, index_col=0, parse_dates=[0])
df.plot()

This is what the simple pandas plot looks like: 这就是简单的熊猫图:

在此处输入图片说明

I would like to plot this similar to the example below, with TMAX and TMIN on primary y-axis (on same scale). 我想将其绘制为类似于以下示例,在主y轴上(相同比例)使用TMAX和TMIN。 在此处输入图片说明

My attempt: 我的尝试:

There's one example I found on the the matplotlib listserv ..I am trying to adapt it to my data but something is not working right...Here's the script. 我在matplotlib listserv上发现了一个示例。我正在尝试使其适应我的数据,但某些方法无法正常工作……这里是脚本。

# multiple_yaxes_with_spines.py

# This is a template Python program for creating plots (line graphs) with 2, 3,
# or 4 y-axes.  (A template program is one that you can readily modify to meet
# your needs).  Almost all user-modifiable code is in Section 2.  For most
# purposes, it should not be necessary to modify anything else.

# Dr. Phillip M. Feldman,  27 Oct, 2009

# Acknowledgment: This program is based on code written by Jae-Joon Lee,
# URL= http://matplotlib.svn.sourceforge.net/viewvc/matplotlib/trunk/matplotlib/
# examples/pylab_examples/multiple_yaxis_with_spines.py?revision=7908&view=markup


# Section 1: Import modules, define functions, and allocate storage.

import matplotlib.pyplot as plt
from numpy import *

def make_patch_spines_invisible(ax):
    ax.set_frame_on(True)
    ax.patch.set_visible(False)
    for sp in ax.spines.itervalues():
        sp.set_visible(False)

def make_spine_invisible(ax, direction):
    if direction in ["right", "left"]:
        ax.yaxis.set_ticks_position(direction)
        ax.yaxis.set_label_position(direction)
    elif direction in ["top", "bottom"]:
        ax.xaxis.set_ticks_position(direction)
        ax.xaxis.set_label_position(direction)
    else:
        raise ValueError("Unknown Direction : %s" % (direction,))

    ax.spines[direction].set_visible(True)

# Create list to store dependent variable data:
y= [0, 0, 0, 0, 0]


# Section 2: Define names of variables and the data to be plotted.

# `labels` stores the names of the independent and dependent variables).  The
# first (zeroth) item in the list is the x-axis label; remaining labels are the
# first y-axis label, second y-axis label, and so on.  There must be at least
# two dependent variables and not more than four.

labels= ['Date', 'Maximum Temperature', 'Solar Radiation',
  'Rainfall', 'Minimum Temperature']

# Plug in your data here, or code equations to generate the data if you wish to
# plot mathematical functions.  x stores values of the independent variable;
# y[1], y[2], ... store values of the dependent variable.  (y[0] is not used).
# All of these objects should be NumPy arrays.

# If you are plotting mathematical functions, you will probably want an array of
# uniformly spaced values of x; such an array can be created using the
# `linspace` function.  For example, to define x as an array of 51 values
# uniformly spaced between 0 and 2, use the following command:

#    x= linspace(0., 2., 51)

# Here is an example of 6 experimentally measured y1-values:

#    y[1]= array( [3, 2.5, 7.3e4, 4, 8, 3] )

# Note that the above statement requires both parentheses and square brackets.

# With a bit of work, one could make this program read the data from a text file
# or Excel worksheet.

# Independent variable:
x = df.index
# First dependent variable:
y[1]= df['TMAX']
# Second dependent variable:
y[2]= df['RAD']
y[3]= df['RAIN']
y[4]= df['TMIN']

# Set line colors here; each color can be specified using a single-letter color
# identifier ('b'= blue, 'r'= red, 'g'= green, 'k'= black, 'y'= yellow,
# 'm'= magenta, 'y'= yellow), an RGB tuple, or almost any standard English color
# name written without spaces, e.g., 'darkred'.  The first element of this list
# is not used.
colors= [' ', '#C82121', '#E48E3C', '#4F88BE', '#CF5ADC']

# Set the line width here.  linewidth=2 is recommended.
linewidth= 2


# Section 3: Generate the plot.

N_dependents= len(labels) - 1
if N_dependents > 4: raise Exception, \
   'This code currently handles a maximum of four independent variables.'

# Open a new figure window, setting the size to 10-by-7 inches and the facecolor
# to white:
fig= plt.figure(figsize=(16,9), dpi=120, facecolor=[1,1,1])

host= fig.add_subplot(111)

host.set_xlabel(labels[0])

# Use twinx() to create extra axes for all dependent variables except the first
# (we get the first as part of the host axes).  The first element of y_axis is
# not used.
y_axis= (N_dependents+2) * [0]
y_axis[1]= host
for i in range(2,len(labels)+1): y_axis[i]= host.twinx()

if N_dependents >= 3:
   # The following statement positions the third y-axis to the right of the
   # frame, with the space between the frame and the axis controlled by the
   # numerical argument to set_position; this value should be between 1.10 and
   # 1.2.
   y_axis[3].spines["right"].set_position(("axes", 1.15))
   make_patch_spines_invisible(y_axis[3])
   make_spine_invisible(y_axis[3], "right")
   plt.subplots_adjust(left=0.0, right=0.8)

if N_dependents >= 4:
   # The following statement positions the fourth y-axis to the left of the
   # frame, with the space between the frame and the axis controlled by the
   # numerical argument to set_position; this value should be between 1.10 and
   # 1.2.
   y_axis[4].spines["left"].set_position(("axes", -0.15))
   make_patch_spines_invisible(y_axis[4])
   make_spine_invisible(y_axis[4], "left")
   plt.subplots_adjust(left=0.2, right=0.8)

p= (N_dependents+1) * [0]

# Plot the curves:
for i in range(1,N_dependents+1):
   p[i], = y_axis[i].plot(x, y[i], colors[i],
     linewidth=linewidth, label=labels[i])

# Set axis limits.  Use ceil() to force upper y-axis limits to be round numbers.
host.set_xlim(x.min(), x.max())

host.set_xlabel(labels[0], size=16)

for i in range(1,N_dependents+1):
   y_axis[i].set_ylim(0.0, ceil(y[i].max()))
   y_axis[i].set_ylabel(labels[i], size=16)
   y_axis[i].yaxis.label.set_color(colors[i])

   for sp in y_axis[i].spines.itervalues():
     sp.set_color(colors[i])

   for obj in y_axis[i].yaxis.get_ticklines():
      # `obj` is a matplotlib.lines.Line2D instance
      obj.set_color(colors[i])
      obj.set_markeredgewidth(3)

   for obj in y_axis[i].yaxis.get_ticklabels():
      obj.set_color(colors[i])
      obj.set_size(12)
      obj.set_weight(600)

# To enable the legend, uncomment the following two lines:
lines= p[1:]
host.legend(lines, [l.get_label() for l in lines])

plt.draw(); plt.show()

And the output 和输出

在此处输入图片说明

How can I put the scale on max and min temp on a same scale? 如何将标度放在最大和最小温度上? Also, how can I get rid of second y-axis with black color, scaled from 0 to 10? 另外,如何摆脱黑色的第二个Y轴(从0缩放到10)?

Is there a simpler way to achieve this? 有没有更简单的方法来实现这一目标?

How can I put the scale on max and min temp on a same scale? 如何将标度放在最大和最小温度上?

Plot them in the same axes. 将它们绘制在相同的轴上。

Also, how can I get rid of second y-axis with black color, scaled from 0 to 10? 另外,如何摆脱黑色的第二个Y轴(从0缩放到10)?

Do not create that axes. 不要创建该轴。

You want to plot four variables, two of them can go in the same subplot so you only need three subplots. 您想绘制四个变量,其中两个可以放在同一子图中,因此只需要三个子图。 But you are creating five of them? 但是您要创建五个?

Step by step 一步步

Keep in mind: different y scales <-> different subplots sharing x-axis. 请记住:不同的y比例尺<->不同的子图共享x轴。

Two variables with a common scale (left), two variables with independent scales (right). 具有相同比例的两个变量(左),具有独立比例的两个变量(右)。

  1. Create the primary subplot, let's call it ax1 . 创建主要子图,将其称为ax1 Plot everything you want in it, in this case TMIN and TMAX as stated in your question. 绘制您想要的所有内容,在本例中为您问题中提到的TMIN和TMAX。
  2. Create a twin subplot sharing x axis twinx(ax=ax1) . 创建一个共享x轴twinx(ax=ax1)的孪生子图。 Plot the third variable, say RAIN. 绘制第三个变量,比如说RAIN。
  3. Create another twin subplot twinx(ax=ax1) . 创建另一个twin子图twinx(ax=ax1) Plot the fourth variable 'RAD'. 绘制第四个变量“ RAD”。
  4. Adjust colors, labels, spine positions... to your heart's content. 调整颜色,标签,脊椎位置……以适应您的心脏。

Unsolicited advice: do not try to fix code you don't understand. 不请自来的建议:请勿尝试修复您不了解的代码。

Variation of the original plot showing how you can plot variables on multiple axes 原始绘图的变体,显示了如何在多个轴上绘制变量

import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

url ='http://dropproxy.com/f/D34'

df= pd.read_csv(url, index_col=0, parse_dates=[0])

fig = plt.figure()

ax = fig.add_subplot(111) # Primary y
ax2 = ax.twinx() # Secondary y

# Plot variables
ax.plot(df.index, df['TMAX'], color='red')
ax.plot(df.index, df['TMIN'], color='green')
ax2.plot(df.index, df['RAIN'], color='orange')
ax2.plot(df.index, df['RAD'],  color='yellow')

# Custom ylimit
ax.set_ylim(0,50)

# Custom x axis date formats
import matplotlib.dates as mdates
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y'))

I modified @bishopo's suggestions to generate what I wanted, however, the plot still needs some tweaking with font sizes for axes label. 我修改了@bishopo的建议以生成我想要的内容,但是,该图仍需要对轴标签的字体大小进行一些调整。

Here's what I have done so far. 到目前为止,这是我所做的。

import pandas as pd
%matplotlib inline

url ='http://dropproxy.com/f/D34'

df= pd.read_csv(url, index_col=0, parse_dates=[0])

from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA
import matplotlib.pyplot as plt





if 1:
    # Set the figure size, dpi, and background color
    fig = plt.figure(1, (16,9),dpi =300, facecolor = 'W',edgecolor ='k')


    # Update the tick label size to 12
    plt.rcParams.update({'font.size': 12})
    host = host_subplot(111, axes_class=AA.Axes)
    plt.subplots_adjust(right=0.75)

    par1 = host.twinx()
    par2 = host.twinx()
    par3 = host.twinx()

    offset = 60

    new_fixed_axis = par2.get_grid_helper().new_fixed_axis
    new_fixed_axis1 = host.get_grid_helper().new_fixed_axis
    par2.axis["right"] = new_fixed_axis(loc="right",
                                        axes=par2,
                                        offset=(offset, 0))
    par3.axis["left"] = new_fixed_axis1(loc="left",
                                        axes=par3,
                                        offset=(-offset, 0))

    par2.axis["right"].toggle(all=True)
    par3.axis["left"].toggle(all=True)
    par3.axis["right"].set_visible(False)


    # Set limit on both y-axes
    host.set_ylim(-30, 50)
    par3.set_ylim(-30,50)

    host.set_xlabel("Date")
    host.set_ylabel("Minimum Temperature ($^\circ$C)")
    par1.set_ylabel("Solar Radiation (W$m^{-2}$)")
    par2.set_ylabel("Rainfall (mm)")
    par3.set_ylabel('Maximum Temperature ($^\circ$C)')


    p1, = host.plot(df.index,df['TMIN'], 'm,')
    p2, = par1.plot(df.index, df.RAD, color ='#EF9600', linestyle ='--')
    p3, = par2.plot(df.index, df.RAIN, '#09BEEF')
    p4, = par3.plot(df.index, df['TMAX'], '#FF8284')

    par1.set_ylim(0, 36)
    par2.set_ylim(0, 360)

    host.legend()


    host.axis["left"].label.set_color(p1.get_color())
    par1.axis["right"].label.set_color(p2.get_color())
    par2.axis["right"].label.set_color(p3.get_color())
    par3.axis["left"].label.set_color(p4.get_color())



    tkw = dict(size=5, width=1.5)
    host.tick_params(axis='y', colors=p1.get_color(), **tkw)
    par1.tick_params(axis='y', colors=p2.get_color(), **tkw)
    par2.tick_params(axis='y', colors=p3.get_color(), **tkw)
    par3.tick_params(axis='y', colors=p4.get_color(), **tkw)
    host.tick_params(axis='x', **tkw)



    par1.axis["right"].label.set_fontsize(16)
    par2.axis["right"].label.set_fontsize(16)
    par3.axis["left"].label.set_fontsize(16)
    host.axis["bottom"].label.set_fontsize(16)
    host.axis["left"].label.set_fontsize(16)


    plt.figtext(.5,.92,'Weather Data', fontsize=22, ha='center')
    plt.draw()
    plt.show()

    fig.savefig("Test1.png") 

The output 输出 在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM