标签归档:matplotlib

将MATLAB代码转换为Python的工具

问题:将MATLAB代码转换为Python的工具

我的MS论文中有一堆MATLAB代码,现在我想将其转换为Python(使用numpy / scipy和matplotlib)并作为开源分发。我知道MATLAB与Python科学库之间的相似之处,手动转换它们的时间不会超过两周(前提是我每天都会努力一段时间)。我想知道是否已经有任何工具可以进行转换。

I have a bunch of MATLAB code from my MS thesis which I now want to convert to Python (using numpy/scipy and matplotlib) and distribute as open-source. I know the similarity between MATLAB and Python scientific libraries, and converting them manually will be not more than a fortnight (provided that I work towards it every day for some time). I was wondering if there was already any tool available which can do the conversion.


回答 0

有几种工具可以将Matlab转换为Python代码。

那见过最近的活动只有一个(最后从2018年6月提交)是小号商场中号 ATLab的牛逼Ø P ython编译器(这里也开发:SMOP @ chiselapp)。

其他选项包括:

  • LiberMate:从Matlab转换为Python和SciPy(需要Python 2,最新更新为4年前)。
  • OMPC:Matlab到Python(有点过时)。

同样,对于那些对两种语言之间的接口感兴趣而不是转换的人:

  • pymatlab:从Python进行通信,方法是将数据发送到MATLAB工作区,使用脚本对其进行操作,然后拉回结果数据。
  • Python-Matlab虫洞:支持双向交互。
  • Python-Matlab桥:从Python内部使用Matlab,为iPython提供matlab_magic,以从ipython内部执行普通的matlab代码。
  • PyMat:从Python控制Matlab会话。
  • pymat2:看似被遗弃的PyMat的延续。
  • mlabwrapmlabwrap-purepy:使Matlab看起来像Python库(基于PyMat)。
  • oct2py:从Python内部运行GNU Octave命令。
  • pymex:将Python解释器嵌入到Matlab以及文件交换中
  • matpy:通过各种方式访问​​MATLAB:创建变量,访问.mat文件,直接连接MATLAB引擎(需要安装MATLAB)。
  • MatPy:Python软件包,用于数值线性代数并使用类似于MatLab的界面进行绘图。

顺便说一句,在这里查找其他迁移技巧可能会有所帮助:

另一方面,尽管我一点也不喜欢,但fortran对于可能会觉得有用的人来说,有:

There are several tools for converting Matlab to Python code.

The only one that’s seen recent activity (last commit from June 2018) is Small Matlab to Python compiler (also developed here: SMOP@chiselapp).

Other options include:

  • LiberMate: translate from Matlab to Python and SciPy (Requires Python 2, last update 4 years ago).
  • OMPC: Matlab to Python (a bit outdated).

Also, for those interested in an interface between the two languages and not conversion:

  • pymatlab: communicate from Python by sending data to the MATLAB workspace, operating on them with scripts and pulling back the resulting data.
  • Python-Matlab wormholes: both directions of interaction supported.
  • Python-Matlab bridge: use Matlab from within Python, offers matlab_magic for iPython, to execute normal matlab code from within ipython.
  • PyMat: Control Matlab session from Python.
  • pymat2: continuation of the seemingly abandoned PyMat.
  • mlabwrap, mlabwrap-purepy: make Matlab look like Python library (based on PyMat).
  • oct2py: run GNU Octave commands from within Python.
  • pymex: Embeds the Python Interpreter in Matlab, also on File Exchange.
  • matpy: Access MATLAB in various ways: create variables, access .mat files, direct interface to MATLAB engine (requires MATLAB be installed).
  • MatPy: Python package for numerical linear algebra and plotting with a MatLab-like interface.

Btw might be helpful to look here for other migration tips:

On a different note, though I’m not a fortran fan at all, for people who might find it useful there is:


回答 1

还有oct2py可以在python中调用.m文件

https://pypi.python.org/pypi/oct2py

它需要GNU Octave,它与MATLAB高度兼容。

https://www.gnu.org/software/octave/

There’s also oct2py which can call .m files within python

https://pypi.python.org/pypi/oct2py

It requires GNU Octave, which is highly compatible with MATLAB.

https://www.gnu.org/software/octave/


Matplotlib中的bin大小(直方图)

问题:Matplotlib中的bin大小(直方图)

我正在使用matplotlib制作直方图。

有什么方法可以手动设置垃圾箱的大小,而不是垃圾箱的数量吗?

I’m using matplotlib to make a histogram.

Is there any way to manually set the size of the bins as opposed to the number of bins?


回答 0

实际上,这很简单:您可以提供一个带有bin边界的列表,而不是bin的数量。它们也可能分布不均:

plt.hist(data, bins=[0, 10, 20, 30, 40, 50, 100])

如果只希望它们均匀分布,则可以使用range:

plt.hist(data, bins=range(min(data), max(data) + binwidth, binwidth))

添加到原始答案

上一行data仅适用于整数填充。正如macrocosme所指出的,对于浮点数,您可以使用:

import numpy as np
plt.hist(data, bins=np.arange(min(data), max(data) + binwidth, binwidth))

Actually, it’s quite easy: instead of the number of bins you can give a list with the bin boundaries. They can be unequally distributed, too:

plt.hist(data, bins=[0, 10, 20, 30, 40, 50, 100])

If you just want them equally distributed, you can simply use range:

plt.hist(data, bins=range(min(data), max(data) + binwidth, binwidth))

Added to original answer

The above line works for data filled with integers only. As macrocosme points out, for floats you can use:

import numpy as np
plt.hist(data, bins=np.arange(min(data), max(data) + binwidth, binwidth))

回答 1

对于N个仓,仓边缘由N + 1个值的列表指定,其中前N个给出较低仓边缘,而+1给出最后一个仓的较高边缘。

码:

from numpy import np; from pylab import *

bin_size = 0.1; min_edge = 0; max_edge = 2.5
N = (max_edge-min_edge)/bin_size; Nplus1 = N + 1
bin_list = np.linspace(min_edge, max_edge, Nplus1)

请注意,linspace产生从min_edge到max_edge的数组,该数组分为N + 1个值或N个bin

For N bins, the bin edges are specified by list of N+1 values where the first N give the lower bin edges and the +1 gives the upper edge of the last bin.

Code:

from numpy import np; from pylab import *

bin_size = 0.1; min_edge = 0; max_edge = 2.5
N = (max_edge-min_edge)/bin_size; Nplus1 = N + 1
bin_list = np.linspace(min_edge, max_edge, Nplus1)

Note that linspace produces array from min_edge to max_edge broken into N+1 values or N bins


回答 2

我猜最简单的方法是计算您拥有的数据的最小值和最大值,然后计算L = max - min。然后L,用所需的箱宽度除(我假设这就是箱大小),然后将该值的上限用作箱数。

I guess the easy way would be to calculate the minimum and maximum of the data you have, then calculate L = max - min. Then you divide L by the desired bin width (I’m assuming this is what you mean by bin size) and use the ceiling of this value as the number of bins.


回答 3

我喜欢事情会自动发生,而垃圾箱却落在“不错的”价值上。以下似乎很好用。

import numpy as np
import numpy.random as random
import matplotlib.pyplot as plt
def compute_histogram_bins(data, desired_bin_size):
    min_val = np.min(data)
    max_val = np.max(data)
    min_boundary = -1.0 * (min_val % desired_bin_size - min_val)
    max_boundary = max_val - max_val % desired_bin_size + desired_bin_size
    n_bins = int((max_boundary - min_boundary) / desired_bin_size) + 1
    bins = np.linspace(min_boundary, max_boundary, n_bins)
    return bins

if __name__ == '__main__':
    data = np.random.random_sample(100) * 123.34 - 67.23
    bins = compute_histogram_bins(data, 10.0)
    print(bins)
    plt.hist(data, bins=bins)
    plt.xlabel('Value')
    plt.ylabel('Counts')
    plt.title('Compute Bins Example')
    plt.grid(True)
    plt.show()

结果以良好的间隔大小间隔包含了间隔。

[-70. -60. -50. -40. -30. -20. -10.   0.  10.  20.  30.  40.  50.  60.]

I like things to happen automatically and for bins to fall on “nice” values. The following seems to work quite well.

import numpy as np
import numpy.random as random
import matplotlib.pyplot as plt
def compute_histogram_bins(data, desired_bin_size):
    min_val = np.min(data)
    max_val = np.max(data)
    min_boundary = -1.0 * (min_val % desired_bin_size - min_val)
    max_boundary = max_val - max_val % desired_bin_size + desired_bin_size
    n_bins = int((max_boundary - min_boundary) / desired_bin_size) + 1
    bins = np.linspace(min_boundary, max_boundary, n_bins)
    return bins

if __name__ == '__main__':
    data = np.random.random_sample(100) * 123.34 - 67.23
    bins = compute_histogram_bins(data, 10.0)
    print(bins)
    plt.hist(data, bins=bins)
    plt.xlabel('Value')
    plt.ylabel('Counts')
    plt.title('Compute Bins Example')
    plt.grid(True)
    plt.show()

The result has bins on nice intervals of bin size.

[-70. -60. -50. -40. -30. -20. -10.   0.  10.  20.  30.  40.  50.  60.]


回答 4

我使用分位数来使容器均匀并适合于采样:

bins=df['Generosity'].quantile([0,.05,0.1,0.15,0.20,0.25,0.3,0.35,0.40,0.45,0.5,0.55,0.6,0.65,0.70,0.75,0.80,0.85,0.90,0.95,1]).to_list()

plt.hist(df['Generosity'], bins=bins, normed=True, alpha=0.5, histtype='stepfilled', color='steelblue', edgecolor='none')

I use quantiles to do bins uniform and fitted to sample:

bins=df['Generosity'].quantile([0,.05,0.1,0.15,0.20,0.25,0.3,0.35,0.40,0.45,0.5,0.55,0.6,0.65,0.70,0.75,0.80,0.85,0.90,0.95,1]).to_list()

plt.hist(df['Generosity'], bins=bins, normed=True, alpha=0.5, histtype='stepfilled', color='steelblue', edgecolor='none')


回答 5

我遇到了与OP相同的问题(我认为!),但是我无法按照Lastalda指定的方式使其正常工作。我不知道我是否正确解释了这个问题,但是我找到了另一种解决方案(尽管这可能是一种非常糟糕的方法)。

我就是这样的:

plt.hist([1,11,21,31,41], bins=[0,10,20,30,40,50], weights=[10,1,40,33,6]);

这创建了这个:

因此,第一个参数基本上是“初始化”垃圾箱-我专门创建一个数字,该数字介于我在垃圾箱参数中设置的范围之间。

为了说明这一点,请查看第一个参数([1,11,21,31,41])中的数组和第二个参数([0,10,20,30,40,50]中的’bins’数组:

  • 数字1(从第一个数组开始)介于0到10之间(在“ bins”数组中)
  • 数字11(来自第一个数组)介于11和20之间(在“ bins”数组中)
  • 数字21(从第一个数组开始)介于21到30(在“ bins”数组中)之间,依此类推。

然后,我使用’weights’参数定义每个垃圾箱的大小。这是用于weights参数的数组:[10,1,40,33,6]。

因此0到10 bin的值是10,11到20 bin的值是1,21到30 bin的值是40,依此类推。

I had the same issue as OP (I think!), but I couldn’t get it to work in the way that Lastalda specified. I don’t know if I have interpreted the question properly, but I have found another solution (it probably is a really bad way of doing it though).

This was the way that I did it:

plt.hist([1,11,21,31,41], bins=[0,10,20,30,40,50], weights=[10,1,40,33,6]);

Which creates this:

So the first parameter basically ‘initialises’ the bin – I’m specifically creating a number that is in between the range I set in the bins parameter.

To demonstrate this, look at the array in the first parameter ([1,11,21,31,41]) and the ‘bins’ array in the second parameter ([0,10,20,30,40,50]):

  • The number 1 (from the first array) falls between 0 and 10 (in the ‘bins’ array)
  • The number 11 (from the first array) falls between 11 and 20 (in the ‘bins’ array)
  • The number 21 (from the first array) falls between 21 and 30 (in the ‘bins’ array), etc.

Then I’m using the ‘weights’ parameter to define the size of each bin. This is the array used for the weights parameter: [10,1,40,33,6].

So the 0 to 10 bin is given the value 10, the 11 to 20 bin is given the value of 1, the 21 to 30 bin is given the value of 40, etc.


回答 6

对于具有整数x值的直方图,我最终使用

plt.hist(data, np.arange(min(data)-0.5, max(data)+0.5))
plt.xticks(range(min(data), max(data)))

0.5的偏移量使分箱在x轴值上居中。该plt.xticks调用为每个整数添加一个刻度。

For a histogram with integer x-values I ended up using

plt.hist(data, np.arange(min(data)-0.5, max(data)+0.5))
plt.xticks(range(min(data), max(data)))

The offset of 0.5 centers the bins on the x-axis values. The plt.xticks call adds a tick for every integer.


ImportError:没有名为matplotlib.pyplot的模块

问题:ImportError:没有名为matplotlib.pyplot的模块

我目前正在练习matplotlib。这是我练习的第一个示例。

#!/usr/bin/python

import matplotlib.pyplot as plt

radius = [1.0, 2.0, 3.0, 4.0]
area = [3.14159, 12.56636, 28.27431, 50.26544]

plt.plot(radius, area)
plt.show()

当我使用运行脚本时python ./plot_test.py,它可以正确显示绘图。但是,我自己运行./plot_test.py,它引发了以下问题:

Traceback (most recent call last):
File "./plot_test.py", line 3, in <module>
  import matplotlib.pyplot as plt
ImportError: No module named matplotlib.pyplot

python是否在不同位置查找matplotlib?

环境是:

Mac OS X 10.8.4 64bit
built-in python 2.7

numpy,scipy,matplotlib已安装:

sudo port install py27-numpy py27-scipy py27-matplotlib \
py27-ipython +notebook py27-pandas py27-sympy py27-nose

I am currently practicing matplotlib. This is the first example I practice.

#!/usr/bin/python

import matplotlib.pyplot as plt

radius = [1.0, 2.0, 3.0, 4.0]
area = [3.14159, 12.56636, 28.27431, 50.26544]

plt.plot(radius, area)
plt.show()

When I run this script with python ./plot_test.py, it shows plot correctly. However, I run it by itself, ./plot_test.py, it throws the followings:

Traceback (most recent call last):
File "./plot_test.py", line 3, in <module>
  import matplotlib.pyplot as plt
ImportError: No module named matplotlib.pyplot

Does python look for matplotlib in different locations?

The environment is:

Mac OS X 10.8.4 64bit
built-in python 2.7

numpy, scipy, matplotlib is installed with:

sudo port install py27-numpy py27-scipy py27-matplotlib \
py27-ipython +notebook py27-pandas py27-sympy py27-nose

回答 0

您的计算机上安装了两个python,一个是Mac OSX随附的标准python,第二个是您使用端口安装的python(这是已matplotlib安装在其库中的一个,而macosx却没有安装)。 。

/usr/bin/python

是标准的mac python,由于没有,所以matplotlib您应该始终使用安装了端口的脚本启动脚本。

如果python your_script.py可行,请将更改#!为:

#!/usr/bin/env python

或将完整路径放入matplotlib已在其库中安装的python解释器。

You have two pythons installed on your machine, one is the standard python that comes with Mac OSX and the second is the one you installed with ports (this is the one that has matplotlib installed in its library, the one that comes with macosx does not).

/usr/bin/python

Is the standard mac python and since it doesn’t have matplotlib you should always start your script with the one installed with ports.

If python your_script.py works then change the #! to:

#!/usr/bin/env python

Or put the full path to the python interpreter that has the matplotlib installed in its library.


回答 1

pip 让您的生活更轻松!

第1步:安装pip-简单地通过在python控制台中编写pip来检查是否已有pip。如果没有pip,请通过以下网址获取一个名为get-pip.py的python脚本:https://pip.pypa.io/en/latest/installing.html或直接在此处:https://bootstrap.pypa .io / get-pip.py(您可能必须使用另存为..)

第2步:记下文件的保存位置,然后从命令提示符下cd目录。运行get-pip.py脚本以安装pip。您可以在cmd这一行中用引号引起来:“ python。\ get-pip.py”

步骤3:现在输入cmd: pip install matplotlib

而你应该通过。

pip will make your life easy!

Step 1: Install pip – Check if you have pip already simply by writing pip in the python console. If you don’t have pip, get a python script called get-pip.py , via here: https://pip.pypa.io/en/latest/installing.html or directly here: https://bootstrap.pypa.io/get-pip.py (You may have to use Save As ..)

Step 2: Take note of where the file got saved and cd the directory from command prompt. Run the get-pip.py script to install pip. You can write in cmd this line within quotes: “python .\get-pip.py”

Step 3: Now in cmd type: pip install matplotlib

And you should be through.


回答 2

如果您使用的是Python 2,请运行

sudo apt-get install python-matplotlib

最好的获取方法matplotlib是:

pip install matplotlib

因为以前的方法可能会给您旧版本 matplotlib

If you are using Python 2, just run

sudo apt-get install python-matplotlib

The best way to get matplotlib is :

pip install matplotlib

cause the previous way may give you a old version of matplotlib


回答 3

这对我有用,受到Sheetal Kaul的启发

pip uninstall matplotlib
python3 -m pip install matplotlib

我知道它在工作时安装在错误的位置:

python2.7
import matplotlib

This worked for me, inspired by Sheetal Kaul

pip uninstall matplotlib
python3 -m pip install matplotlib

I knew it installed in the wrong place when this worked:

python2.7
import matplotlib

回答 4

python的第一个检查版本

对于python2 Vesion

sudo apt-get install python-matplotlib

对于python3版本

sudo apt-get install python3-matplotlib

如果您将python版本的matplotlib安装错过匹配,则会出现“无模块错误”,因为该版本没有模块退出。

First check the version of Python

For python2:

sudo apt-get install python-matplotlib

For python3:

sudo apt-get install python3-matplotlib

If you mismatch the Matplotlib installation and the Python version you will get the no-module-error because no module for that version exits.


回答 5

对于python3。只需运行pip3 install matplotlib

For python3. Just need to run pip3 install matplotlib


回答 6

如果您使用Anaconda3

刚放

conda install -c conda-forge matplotlib

If you using Anaconda3

Just put

conda install -c conda-forge matplotlib

回答 7

我有一个类似的问题已解决,这是我的问题:

我在python3上进行了所有设置,但是例如,我使用python来调用我的文件:我正在输入“ python mnist.py” …因为我在python3上拥有所有内容,所以我认为我正在尝试使用python 2.7

的更正:“ python3 mnist.py”-3使一切有所不同

我绝不是python或pip的专家,但是pip和pip3之间肯定有区别(pip与python 2.7绑定)(pip3与python 3.6绑定)

因此,当安装2.7时要执行:pip安装当安装3.6时要执行:pip3安装

当运行2.7的代码时执行:python运行3.6的代码时执行:python3

我希望这可以帮助别人!

I had a similar issue that I resolved and here is my issue:

I set everything up on python3 but I was using python to call my file for example: I was typing “python mnist.py” …since I have everything on python3 it was thinking I was trying to use python 2.7

The correction: “python3 mnist.py” – the 3 made all the difference

I’m by no means an expert in python or pip, but there is definitely a difference between pip and pip3 (pip is tied to python 2.7) (pip3 is tied to python 3.6)

so when installing for 2.7 do: pip install when installing for 3.6 do: pip3 install

and when running your code for 2.7 do: python when running your code for 3.6 do: python3

I hope this helps someone!


回答 8

正常供稿中的评论被屏蔽。让我写下为什么会发生这种情况,就像您执行应用程序时一样。

如果在安装环境之外的其他环境中运行脚本,python或ipython,则会遇到这些问题。

不要混淆重新安装它。Matplotlib通常安装在您的用户环境中,而不是sudo中。您正在改变环境。

因此,不要重新安装pip,只要将其安装在sudo环境中,请确保将其作为sudo运行。

Comment in the normal feed are blocked. Let me write why this happens, just like when you executed your app.

If you ran scripts, python or ipython in another environment than the one you installed it, you will get these issues.

Don’t confuse reinstalling it. Matplotlib is normally installed in your user environment, not in sudo. You are changing the environment.

So don’t reinstall pip, just make sure you are running it as sudo if you installed it in the sudo environment.


回答 9

我花了好几个小时不停地思考,直到我想检查一下.bash_profile为止。我没有列出python3的路径,因此添加了以下代码:

# Setting PATH for Python 3.6
# The original version is saved in .bash_profile.pysave
PATH="/Library/Frameworks/Python.framework/Versions/3.6/bin:${PATH}"
export PATH

然后使用重新安装matplotlib sudo pip3 install matplotlib。现在一切都运转良好。

I bashed my head on this for hours until I thought about checking my .bash_profile. I didn’t have a path listed for python3 so I added the following code:

# Setting PATH for Python 3.6
# The original version is saved in .bash_profile.pysave
PATH="/Library/Frameworks/Python.framework/Versions/3.6/bin:${PATH}"
export PATH

And then re-installed matplotlib with sudo pip3 install matplotlib. All is working beautifully now.


回答 10

因此,我将python3 -m pip install matplotlib' thenimport matplotlib.pyplot用作plt`,并且有效。

So I used python3 -m pip install matplotlib' thenimport matplotlib.pyplot as plt` and it worked.


我如何告诉Matplotlib创建第二个(新的)图,然后在旧的图上进行更新?

问题:我如何告诉Matplotlib创建第二个(新的)图,然后在旧的图上进行更新?

我想绘制数据,然后创建一个新图形并绘制数据2,最后回到原始绘制并绘制数据3,有点像这样:

import numpy as np
import matplotlib as plt

x = arange(5)
y = np.exp(5)
plt.figure()
plt.plot(x, y)

z = np.sin(x)
plt.figure()
plt.plot(x, z)

w = np.cos(x)
plt.figure("""first figure""") # Here's the part I need
plt.plot(x, w)

仅供参考,我如何告诉matplotlib我已经完成了一个情节?做类似的事情,但不完全相同!它并不允许我访问该原始图。

I want to plot data, then create a new figure and plot data2, and finally come back to the original plot and plot data3, kinda like this:

import numpy as np
import matplotlib as plt

x = arange(5)
y = np.exp(5)
plt.figure()
plt.plot(x, y)

z = np.sin(x)
plt.figure()
plt.plot(x, z)

w = np.cos(x)
plt.figure("""first figure""") # Here's the part I need
plt.plot(x, w)

FYI How do I tell matplotlib that I am done with a plot? does something similar, but not quite! It doesn’t let me get access to that original plot.


回答 0

如果您发现自己定期执行此类操作,则可能值得研究matplotlib的面向对象的接口。在您的情况下:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(5)
y = np.exp(x)
fig1, ax1 = plt.subplots()
ax1.plot(x, y)
ax1.set_title("Axis 1 title")
ax1.set_xlabel("X-label for axis 1")

z = np.sin(x)
fig2, (ax2, ax3) = plt.subplots(nrows=2, ncols=1) # two axes on figure
ax2.plot(x, z)
ax3.plot(x, -z)

w = np.cos(x)
ax1.plot(x, w) # can continue plotting on the first axis

它稍微冗长一些,但是更容易跟踪,尤其是在几个具有多个子图的图形上。

If you find yourself doing things like this regularly it may be worth investigating the object-oriented interface to matplotlib. In your case:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(5)
y = np.exp(x)
fig1, ax1 = plt.subplots()
ax1.plot(x, y)
ax1.set_title("Axis 1 title")
ax1.set_xlabel("X-label for axis 1")

z = np.sin(x)
fig2, (ax2, ax3) = plt.subplots(nrows=2, ncols=1) # two axes on figure
ax2.plot(x, z)
ax3.plot(x, -z)

w = np.cos(x)
ax1.plot(x, w) # can continue plotting on the first axis

It is a little more verbose but it’s much clearer and easier to keep track of, especially with several figures each with multiple subplots.


回答 1

调用时figure,只需为图编号即可。

x = arange(5)
y = np.exp(5)
plt.figure(0)
plt.plot(x, y)

z = np.sin(x)
plt.figure(1)
plt.plot(x, z)

w = np.cos(x)
plt.figure(0) # Here's the part I need
plt.plot(x, w)

编辑:请注意,您可以根据需要对图进行编号(从此处开始0),但是如果在创建新图形时根本不提供图形编号,则自动编号将以1(“ Matlab Style”到文档)。

When you call figure, simply number the plot.

x = arange(5)
y = np.exp(5)
plt.figure(0)
plt.plot(x, y)

z = np.sin(x)
plt.figure(1)
plt.plot(x, z)

w = np.cos(x)
plt.figure(0) # Here's the part I need
plt.plot(x, w)

Edit: Note that you can number the plots however you want (here, starting from 0) but if you don’t provide figure with a number at all when you create a new one, the automatic numbering will start at 1 (“Matlab Style” according to the docs).


回答 2

但是,编号从开始1,因此:

x = arange(5)
y = np.exp(5)
plt.figure(1)
plt.plot(x, y)

z = np.sin(x)
plt.figure(2)
plt.plot(x, z)

w = np.cos(x)
plt.figure(1) # Here's the part I need, but numbering starts at 1!
plt.plot(x, w)

同样,如果图形上有多个轴(例如子图),请使用axes(h)命令where h是所需轴对象的句柄来集中于该轴。

(尚无评论权限,对不起,新答案!)

However, numbering starts at 1, so:

x = arange(5)
y = np.exp(5)
plt.figure(1)
plt.plot(x, y)

z = np.sin(x)
plt.figure(2)
plt.plot(x, z)

w = np.cos(x)
plt.figure(1) # Here's the part I need, but numbering starts at 1!
plt.plot(x, w)

Also, if you have multiple axes on a figure, such as subplots, use the axes(h) command where h is the handle of the desired axes object to focus on that axes.

(don’t have comment privileges yet, sorry for new answer!)


回答 3

经过一番努力后,我发现的一种方法是创建一个函数,该函数以data_plot矩阵,文件名和顺序作为参数,以根据顺序图中的给定数据(不同的顺序=不同的图)创建箱形图并将其保存在给定的file_name下。

def plotFigure(data_plot,file_name,order):
    fig = plt.figure(order, figsize=(9, 6))
    ax = fig.add_subplot(111)
    bp = ax.boxplot(data_plot)
    fig.savefig(file_name, bbox_inches='tight')
    plt.close()

One way I found after some struggling is creating a function which gets data_plot matrix, file name and order as parameter to create boxplots from the given data in the ordered figure (different orders = different figures) and save it under the given file_name.

def plotFigure(data_plot,file_name,order):
    fig = plt.figure(order, figsize=(9, 6))
    ax = fig.add_subplot(111)
    bp = ax.boxplot(data_plot)
    fig.savefig(file_name, bbox_inches='tight')
    plt.close()

将鼠标悬停在matplotlib中的某个点上时可以显示标签吗?

问题:将鼠标悬停在matplotlib中的某个点上时可以显示标签吗?

我正在使用matplotlib制作散点图。散点图上的每个点都与一个命名对象相关联。当我将光标悬停在与该对象关联的散点图上的点上时,我希望能够看到该对象的名称。尤其是,能够快速查看异常点的名称将是很好的。我在此处搜索时能够找到的最接近的东西是注释命令,但这似乎在绘图上创建了固定标签。不幸的是,根据我拥有的点数,如果我标记每个点,则散点图将无法读取。有谁知道一种创建仅在光标悬停在该点附近时才会显示的标签的方法吗?

I am using matplotlib to make scatter plots. Each point on the scatter plot is associated with a named object. I would like to be able to see the name of an object when I hover my cursor over the point on the scatter plot associated with that object. In particular, it would be nice to be able to quickly see the names of the points that are outliers. The closest thing I have been able to find while searching here is the annotate command, but that appears to create a fixed label on the plot. Unfortunately, with the number of points that I have, the scatter plot would be unreadable if I labeled each point. Does anyone know of a way to create labels that only appear when the cursor hovers in the vicinity of that point?


回答 0

似乎这里没有其他答案可以真正回答这个问题。因此,这是一个使用散点图的代码,并在将鼠标悬停在散点上时显示了注释

import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)

x = np.random.rand(15)
y = np.random.rand(15)
names = np.array(list("ABCDEFGHIJKLMNO"))
c = np.random.randint(1,5,size=15)

norm = plt.Normalize(1,4)
cmap = plt.cm.RdYlGn

fig,ax = plt.subplots()
sc = plt.scatter(x,y,c=c, s=100, cmap=cmap, norm=norm)

annot = ax.annotate("", xy=(0,0), xytext=(20,20),textcoords="offset points",
                    bbox=dict(boxstyle="round", fc="w"),
                    arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)

def update_annot(ind):

    pos = sc.get_offsets()[ind["ind"][0]]
    annot.xy = pos
    text = "{}, {}".format(" ".join(list(map(str,ind["ind"]))), 
                           " ".join([names[n] for n in ind["ind"]]))
    annot.set_text(text)
    annot.get_bbox_patch().set_facecolor(cmap(norm(c[ind["ind"][0]])))
    annot.get_bbox_patch().set_alpha(0.4)


def hover(event):
    vis = annot.get_visible()
    if event.inaxes == ax:
        cont, ind = sc.contains(event)
        if cont:
            update_annot(ind)
            annot.set_visible(True)
            fig.canvas.draw_idle()
        else:
            if vis:
                annot.set_visible(False)
                fig.canvas.draw_idle()

fig.canvas.mpl_connect("motion_notify_event", hover)

plt.show()

由于人们也希望将此解决方案用于行plot而不是分散,因此以下内容将是相同的解决方案plot(其工作原理略有不同)。

import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)

x = np.sort(np.random.rand(15))
y = np.sort(np.random.rand(15))
names = np.array(list("ABCDEFGHIJKLMNO"))

norm = plt.Normalize(1,4)
cmap = plt.cm.RdYlGn

fig,ax = plt.subplots()
line, = plt.plot(x,y, marker="o")

annot = ax.annotate("", xy=(0,0), xytext=(-20,20),textcoords="offset points",
                    bbox=dict(boxstyle="round", fc="w"),
                    arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)

def update_annot(ind):
    x,y = line.get_data()
    annot.xy = (x[ind["ind"][0]], y[ind["ind"][0]])
    text = "{}, {}".format(" ".join(list(map(str,ind["ind"]))), 
                           " ".join([names[n] for n in ind["ind"]]))
    annot.set_text(text)
    annot.get_bbox_patch().set_alpha(0.4)


def hover(event):
    vis = annot.get_visible()
    if event.inaxes == ax:
        cont, ind = line.contains(event)
        if cont:
            update_annot(ind)
            annot.set_visible(True)
            fig.canvas.draw_idle()
        else:
            if vis:
                annot.set_visible(False)
                fig.canvas.draw_idle()

fig.canvas.mpl_connect("motion_notify_event", hover)

plt.show()

如果有人正在寻找双轴上的线的解决方案,请参阅如何将鼠标悬停在多轴上的点上时显示标签?

如果有人正在寻找条形图的解决方案,请参考此答案

It seems none of the other answers here actually answer the question. So here is a code that uses a scatter and shows an annotation upon hovering over the scatter points.

import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)

x = np.random.rand(15)
y = np.random.rand(15)
names = np.array(list("ABCDEFGHIJKLMNO"))
c = np.random.randint(1,5,size=15)

norm = plt.Normalize(1,4)
cmap = plt.cm.RdYlGn

fig,ax = plt.subplots()
sc = plt.scatter(x,y,c=c, s=100, cmap=cmap, norm=norm)

annot = ax.annotate("", xy=(0,0), xytext=(20,20),textcoords="offset points",
                    bbox=dict(boxstyle="round", fc="w"),
                    arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)

def update_annot(ind):

    pos = sc.get_offsets()[ind["ind"][0]]
    annot.xy = pos
    text = "{}, {}".format(" ".join(list(map(str,ind["ind"]))), 
                           " ".join([names[n] for n in ind["ind"]]))
    annot.set_text(text)
    annot.get_bbox_patch().set_facecolor(cmap(norm(c[ind["ind"][0]])))
    annot.get_bbox_patch().set_alpha(0.4)


def hover(event):
    vis = annot.get_visible()
    if event.inaxes == ax:
        cont, ind = sc.contains(event)
        if cont:
            update_annot(ind)
            annot.set_visible(True)
            fig.canvas.draw_idle()
        else:
            if vis:
                annot.set_visible(False)
                fig.canvas.draw_idle()

fig.canvas.mpl_connect("motion_notify_event", hover)

plt.show()

Because people also want to use this solution for a line plot instead of a scatter, the following would be the same solution for plot (which works slightly differently).

import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)

x = np.sort(np.random.rand(15))
y = np.sort(np.random.rand(15))
names = np.array(list("ABCDEFGHIJKLMNO"))

norm = plt.Normalize(1,4)
cmap = plt.cm.RdYlGn

fig,ax = plt.subplots()
line, = plt.plot(x,y, marker="o")

annot = ax.annotate("", xy=(0,0), xytext=(-20,20),textcoords="offset points",
                    bbox=dict(boxstyle="round", fc="w"),
                    arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)

def update_annot(ind):
    x,y = line.get_data()
    annot.xy = (x[ind["ind"][0]], y[ind["ind"][0]])
    text = "{}, {}".format(" ".join(list(map(str,ind["ind"]))), 
                           " ".join([names[n] for n in ind["ind"]]))
    annot.set_text(text)
    annot.get_bbox_patch().set_alpha(0.4)


def hover(event):
    vis = annot.get_visible()
    if event.inaxes == ax:
        cont, ind = line.contains(event)
        if cont:
            update_annot(ind)
            annot.set_visible(True)
            fig.canvas.draw_idle()
        else:
            if vis:
                annot.set_visible(False)
                fig.canvas.draw_idle()

fig.canvas.mpl_connect("motion_notify_event", hover)

plt.show()

In case someone is looking for a solution for lines in twin axes, refer to How to make labels appear when hovering over a point in multiple axis?

In case someone is looking for a solution for bar plots, please refer to e.g. this answer.


回答 1

当悬停一行而不需要单击它时,此解决方案有效:

import matplotlib.pyplot as plt

# Need to create as global variable so our callback(on_plot_hover) can access
fig = plt.figure()
plot = fig.add_subplot(111)

# create some curves
for i in range(4):
    # Giving unique ids to each data member
    plot.plot(
        [i*1,i*2,i*3,i*4],
        gid=i)

def on_plot_hover(event):
    # Iterating over each data member plotted
    for curve in plot.get_lines():
        # Searching which data member corresponds to current mouse position
        if curve.contains(event)[0]:
            print "over %s" % curve.get_gid()

fig.canvas.mpl_connect('motion_notify_event', on_plot_hover)           
plt.show()

This solution works when hovering a line without the need to click it:

import matplotlib.pyplot as plt

# Need to create as global variable so our callback(on_plot_hover) can access
fig = plt.figure()
plot = fig.add_subplot(111)

# create some curves
for i in range(4):
    # Giving unique ids to each data member
    plot.plot(
        [i*1,i*2,i*3,i*4],
        gid=i)

def on_plot_hover(event):
    # Iterating over each data member plotted
    for curve in plot.get_lines():
        # Searching which data member corresponds to current mouse position
        if curve.contains(event)[0]:
            print "over %s" % curve.get_gid()

fig.canvas.mpl_connect('motion_notify_event', on_plot_hover)           
plt.show()

回答 2

http://matplotlib.sourceforge.net/examples/event_handling/pick_event_demo.html中

from matplotlib.pyplot import figure, show
import numpy as npy
from numpy.random import rand


if 1: # picking on a scatter plot (matplotlib.collections.RegularPolyCollection)

    x, y, c, s = rand(4, 100)
    def onpick3(event):
        ind = event.ind
        print('onpick3 scatter:', ind, npy.take(x, ind), npy.take(y, ind))

    fig = figure()
    ax1 = fig.add_subplot(111)
    col = ax1.scatter(x, y, 100*s, c, picker=True)
    #fig.savefig('pscoll.eps')
    fig.canvas.mpl_connect('pick_event', onpick3)

show()

From http://matplotlib.sourceforge.net/examples/event_handling/pick_event_demo.html :

from matplotlib.pyplot import figure, show
import numpy as npy
from numpy.random import rand


if 1: # picking on a scatter plot (matplotlib.collections.RegularPolyCollection)

    x, y, c, s = rand(4, 100)
    def onpick3(event):
        ind = event.ind
        print('onpick3 scatter:', ind, npy.take(x, ind), npy.take(y, ind))

    fig = figure()
    ax1 = fig.add_subplot(111)
    col = ax1.scatter(x, y, 100*s, c, picker=True)
    #fig.savefig('pscoll.eps')
    fig.canvas.mpl_connect('pick_event', onpick3)

show()

回答 3

http://matplotlib.org/users/shell.html中提供的示例进行略微编辑:

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title('click on points')

line, = ax.plot(np.random.rand(100), '-', picker=5)  # 5 points tolerance


def onpick(event):
    thisline = event.artist
    xdata = thisline.get_xdata()
    ydata = thisline.get_ydata()
    ind = event.ind
    print('onpick points:', *zip(xdata[ind], ydata[ind]))


fig.canvas.mpl_connect('pick_event', onpick)

plt.show()

正如Sohaib所问的那样,这是一条直线图

A slight edit on an example provided in http://matplotlib.org/users/shell.html:

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title('click on points')

line, = ax.plot(np.random.rand(100), '-', picker=5)  # 5 points tolerance


def onpick(event):
    thisline = event.artist
    xdata = thisline.get_xdata()
    ydata = thisline.get_ydata()
    ind = event.ind
    print('onpick points:', *zip(xdata[ind], ydata[ind]))


fig.canvas.mpl_connect('pick_event', onpick)

plt.show()

This plots a straight line plot, as Sohaib was asking


回答 4

mpld3为我解决。编辑(添加代码):

import matplotlib.pyplot as plt
import numpy as np
import mpld3

fig, ax = plt.subplots(subplot_kw=dict(axisbg='#EEEEEE'))
N = 100

scatter = ax.scatter(np.random.normal(size=N),
                 np.random.normal(size=N),
                 c=np.random.random(size=N),
                 s=1000 * np.random.random(size=N),
                 alpha=0.3,
                 cmap=plt.cm.jet)
ax.grid(color='white', linestyle='solid')

ax.set_title("Scatter Plot (with tooltips!)", size=20)

labels = ['point {0}'.format(i + 1) for i in range(N)]
tooltip = mpld3.plugins.PointLabelTooltip(scatter, labels=labels)
mpld3.plugins.connect(fig, tooltip)

mpld3.show()

您可以检查这个例子

mpld3 solve it for me. EDIT (CODE ADDED):

import matplotlib.pyplot as plt
import numpy as np
import mpld3

fig, ax = plt.subplots(subplot_kw=dict(axisbg='#EEEEEE'))
N = 100

scatter = ax.scatter(np.random.normal(size=N),
                 np.random.normal(size=N),
                 c=np.random.random(size=N),
                 s=1000 * np.random.random(size=N),
                 alpha=0.3,
                 cmap=plt.cm.jet)
ax.grid(color='white', linestyle='solid')

ax.set_title("Scatter Plot (with tooltips!)", size=20)

labels = ['point {0}'.format(i + 1) for i in range(N)]
tooltip = mpld3.plugins.PointLabelTooltip(scatter, labels=labels)
mpld3.plugins.connect(fig, tooltip)

mpld3.show()

You can check this example


回答 5

放大器为我工作。mplcursors为matplotlib提供可点击的注释。它受到mpldatacursor(https://github.com/joferkington/mpldatacursor)的启发,并具有简化的API

import matplotlib.pyplot as plt
import numpy as np
import mplcursors

data = np.outer(range(10), range(1, 5))

fig, ax = plt.subplots()
lines = ax.plot(data)
ax.set_title("Click somewhere on a line.\nRight-click to deselect.\n"
             "Annotations can be dragged.")

mplcursors.cursor(lines) # or just mplcursors.cursor()

plt.show()

mplcursors worked for me. mplcursors provides clickable annotation for matplotlib. It is heavily inspired from mpldatacursor (https://github.com/joferkington/mpldatacursor), with a much simplified API

import matplotlib.pyplot as plt
import numpy as np
import mplcursors

data = np.outer(range(10), range(1, 5))

fig, ax = plt.subplots()
lines = ax.plot(data)
ax.set_title("Click somewhere on a line.\nRight-click to deselect.\n"
             "Annotations can be dragged.")

mplcursors.cursor(lines) # or just mplcursors.cursor()

plt.show()

回答 6

其他答案未满足我在最新版本的Jupyter内联matplotlib图形中正确显示工具提示的需求。虽然这一作品:

import matplotlib.pyplot as plt
import numpy as np
import mplcursors
np.random.seed(42)

fig, ax = plt.subplots()
ax.scatter(*np.random.random((2, 26)))
ax.set_title("Mouse over a point")
crs = mplcursors.cursor(ax,hover=True)

crs.connect("add", lambda sel: sel.annotation.set_text(
    'Point {},{}'.format(sel.target[0], sel.target[1])))
plt.show()

当用鼠标越过一点时会导致如下图所示:

The other answers did not address my need for properly showing tooltips in a recent version of Jupyter inline matplotlib figure. This one works though:

import matplotlib.pyplot as plt
import numpy as np
import mplcursors
np.random.seed(42)

fig, ax = plt.subplots()
ax.scatter(*np.random.random((2, 26)))
ax.set_title("Mouse over a point")
crs = mplcursors.cursor(ax,hover=True)

crs.connect("add", lambda sel: sel.annotation.set_text(
    'Point {},{}'.format(sel.target[0], sel.target[1])))
plt.show()

Leading to something like the following picture when going over a point with mouse:


回答 7

如果使用jupyter笔记本,我的解决方案很简单:

%pylab
import matplotlib.pyplot as plt
import mplcursors
plt.plot(...)
mplcursors.cursor(hover=True)
plt.show()

你可以得到类似的东西

If you use jupyter notebook, my solution is as simple as:

%pylab
import matplotlib.pyplot as plt
import mplcursors
plt.plot(...)
mplcursors.cursor(hover=True)
plt.show()

YOu can get something like


回答 8

我制作了一个多行注释系统以添加到:https : //stackoverflow.com/a/47166787/10302020。最新版本:https : //github.com/AidenBurgess/MultiAnnotationLineGraph

只需在底部更改数据。

import matplotlib.pyplot as plt


def update_annot(ind, line, annot, ydata):
    x, y = line.get_data()
    annot.xy = (x[ind["ind"][0]], y[ind["ind"][0]])
    # Get x and y values, then format them to be displayed
    x_values = " ".join(list(map(str, ind["ind"])))
    y_values = " ".join(str(ydata[n]) for n in ind["ind"])
    text = "{}, {}".format(x_values, y_values)
    annot.set_text(text)
    annot.get_bbox_patch().set_alpha(0.4)


def hover(event, line_info):
    line, annot, ydata = line_info
    vis = annot.get_visible()
    if event.inaxes == ax:
        # Draw annotations if cursor in right position
        cont, ind = line.contains(event)
        if cont:
            update_annot(ind, line, annot, ydata)
            annot.set_visible(True)
            fig.canvas.draw_idle()
        else:
            # Don't draw annotations
            if vis:
                annot.set_visible(False)
                fig.canvas.draw_idle()


def plot_line(x, y):
    line, = plt.plot(x, y, marker="o")
    # Annotation style may be changed here
    annot = ax.annotate("", xy=(0, 0), xytext=(-20, 20), textcoords="offset points",
                        bbox=dict(boxstyle="round", fc="w"),
                        arrowprops=dict(arrowstyle="->"))
    annot.set_visible(False)
    line_info = [line, annot, y]
    fig.canvas.mpl_connect("motion_notify_event",
                           lambda event: hover(event, line_info))


# Your data values to plot
x1 = range(21)
y1 = range(0, 21)
x2 = range(21)
y2 = range(0, 42, 2)
# Plot line graphs
fig, ax = plt.subplots()
plot_line(x1, y1)
plot_line(x2, y2)
plt.show()

I have made a multi-line annotation system to add to: https://stackoverflow.com/a/47166787/10302020. for the most up to date version: https://github.com/AidenBurgess/MultiAnnotationLineGraph

Simply change the data in the bottom section.

import matplotlib.pyplot as plt


def update_annot(ind, line, annot, ydata):
    x, y = line.get_data()
    annot.xy = (x[ind["ind"][0]], y[ind["ind"][0]])
    # Get x and y values, then format them to be displayed
    x_values = " ".join(list(map(str, ind["ind"])))
    y_values = " ".join(str(ydata[n]) for n in ind["ind"])
    text = "{}, {}".format(x_values, y_values)
    annot.set_text(text)
    annot.get_bbox_patch().set_alpha(0.4)


def hover(event, line_info):
    line, annot, ydata = line_info
    vis = annot.get_visible()
    if event.inaxes == ax:
        # Draw annotations if cursor in right position
        cont, ind = line.contains(event)
        if cont:
            update_annot(ind, line, annot, ydata)
            annot.set_visible(True)
            fig.canvas.draw_idle()
        else:
            # Don't draw annotations
            if vis:
                annot.set_visible(False)
                fig.canvas.draw_idle()


def plot_line(x, y):
    line, = plt.plot(x, y, marker="o")
    # Annotation style may be changed here
    annot = ax.annotate("", xy=(0, 0), xytext=(-20, 20), textcoords="offset points",
                        bbox=dict(boxstyle="round", fc="w"),
                        arrowprops=dict(arrowstyle="->"))
    annot.set_visible(False)
    line_info = [line, annot, y]
    fig.canvas.mpl_connect("motion_notify_event",
                           lambda event: hover(event, line_info))


# Your data values to plot
x1 = range(21)
y1 = range(0, 21)
x2 = range(21)
y2 = range(0, 42, 2)
# Plot line graphs
fig, ax = plt.subplots()
plot_line(x1, y1)
plot_line(x2, y2)
plt.show()

运行`pip install`的Ubuntu给出错误’无法构建以下必需的软件包:* freetype’

问题:运行`pip install`的Ubuntu给出错误’无法构建以下必需的软件包:* freetype’

执行时pip install -r requirements.txt,在安装阶段出现以下错误matplotlib

REQUIRED DEPENDENCIES AND EXTENSIONS
                 numpy: yes [not found. pip may install it below.]
              dateutil: yes [dateutil was not found. It is required for date
                        axis support. pip/easy_install may attempt to
                        install it after matplotlib.]
               tornado: yes [tornado was not found. It is required for the
                        WebAgg backend. pip/easy_install may attempt to
                        install it after matplotlib.]
             pyparsing: yes [pyparsing was not found. It is required for
                        mathtext support. pip/easy_install may attempt to
                        install it after matplotlib.]
                 pycxx: yes [Couldn't import.  Using local copy.]
                libagg: yes [pkg-config information for 'libagg' could not
                        be found. Using local copy.]
              freetype: no  [pkg-config information for 'freetype2' could
                        not be found.]

The following required packages can not be built:

                    * freetype

还不应该pip install -r requirements.txt安装freetype吗?freetype应该如何在Ubuntu 12.04中安装以便与它一起使用matplotlib

When performing pip install -r requirements.txt, I get the following error during the stage where it is installing matplotlib:

REQUIRED DEPENDENCIES AND EXTENSIONS
                 numpy: yes [not found. pip may install it below.]
              dateutil: yes [dateutil was not found. It is required for date
                        axis support. pip/easy_install may attempt to
                        install it after matplotlib.]
               tornado: yes [tornado was not found. It is required for the
                        WebAgg backend. pip/easy_install may attempt to
                        install it after matplotlib.]
             pyparsing: yes [pyparsing was not found. It is required for
                        mathtext support. pip/easy_install may attempt to
                        install it after matplotlib.]
                 pycxx: yes [Couldn't import.  Using local copy.]
                libagg: yes [pkg-config information for 'libagg' could not
                        be found. Using local copy.]
              freetype: no  [pkg-config information for 'freetype2' could
                        not be found.]

The following required packages can not be built:

                    * freetype

Shouldn’t pip install -r requirements.txt also install freetype? How should freetype be installed in Ubuntu 12.04 so it works with matplotlib?


回答 0

否。pip不会安装系统级别的依赖项。这意味着pip将不会安装RPM(基于Redhat的系统)或DEB(基于Debian的系统)。

要安装系统依赖项,您将需要根据系统使用以下方法之一。

Ubuntu / Debian:

apt-get install libfreetype6-dev

要在基于Ubuntu / Debian的系统上搜索软件包:

apt-cache search <string>

例如:

apt-cache search freetype | grep dev

Redhat / CentOS / Fedora:

yum -y install freetype-devel

要在基于Redhat / CentOS / Fedora的系统上搜索软件包:

yum search <string>

例如:

yum search freetype | grep devel

Mac OS X的:通过自制

brew install freetype

在基于Mac OS X的系统上搜索软件包:

brew search <string>

例如:

brew search freetype

No. pip will not install system-level dependencies. This means pip will not install RPM(s) (Redhat based systems) or DEB(s) (Debian based systems).

To install system dependencies you will need to use one of the following methods depending on your system.

Ubuntu/Debian:

apt-get install libfreetype6-dev

To search for packages on Ubuntu/Debian based systems:

apt-cache search <string>

e.g:

apt-cache search freetype | grep dev

Redhat/CentOS/Fedora:

yum -y install freetype-devel

To search for packages on Redhat/CentOS/Fedora based systems:

yum search <string>

e.g:

yum search freetype | grep devel

Mac OS X: (via Homebrew)

brew install freetype

To search for packages on Mac OS X based systems:

brew search <string>

e.g:

brew search freetype

回答 1

我必须安装libxft-dev才能在ubuntu服务器14.04上启用matplotlib。

sudo apt-get install libfreetype6-dev libxft-dev

然后我可以使用

sudo easy_install matplotlib

I had to install libxft-dev in order to enable matplotlib on ubuntu server 14.04.

sudo apt-get install libfreetype6-dev libxft-dev

And then I could use

sudo easy_install matplotlib

回答 2

sudo apt-get install pkg-config在此github问题中发现一种解决方法。

A workaround is to do sudo apt-get install pkg-config which I found in this github issue.


回答 3

现有的答案都无法在Ubuntu上升级matplotlib。这最终对我有用:

$ sudo apt-get install build-dep python-matplotlib
$ pip install matplotlib --upgrade

None of the existing answers worked for me to upgrade matplotlib on Ubuntu. This is what ultimately work for me:

$ sudo apt-get install build-dep python-matplotlib
$ pip install matplotlib --upgrade

回答 4

此命令将下载所有依赖项。

对于python 2.x

sudo apt-get install python-matplotlib

对于python 3.x

sudo apt-get install python3-matplotlib

安装后,您可以尝试

(sudo) pip install matplotlib

This command will download all dependencies.

For python 2.x

sudo apt-get install python-matplotlib

For python 3.x

sudo apt-get install python3-matplotlib

After installing, you can try

(sudo) pip install matplotlib

回答 5

在Ubuntu上,安装blt-dev软件包后它可以工作。

$sudo apt-get install blt-dev
$pip install matplotlib

On Ubuntu, it worked after I installed blt-dev package.

$sudo apt-get install blt-dev
$pip install matplotlib

回答 6

我正在使用Mint,但以下答案均不适合我,我需要:

sudo apt-get install build-essential g++

I’m using Mint an none of this answers worked for me, I needed to:

sudo apt-get install build-essential g++

回答 7

我在Windows上使用Python 3.6时遇到了同样的问题,但是后来我切换到Python 3.5.2,一切正常。

I had the same issue with Python 3.6 on Windows, but then I switched to Python 3.5.2 and everything works fine.


回答 8

这个命令sudo apt-get install libfreetype6-dev对我来说在Ubuntu 16.04上失败了,
The following packages have unmet dependencies: libfreetype6-dev : Depends: libfreetype6 (= 2.6.1-0.1ubuntu2) but 2.6.1-0.1ubuntu2.3 is to be installed

因此,我从源代码下载了已安装的freetype ,请参考本指南

$ tar -xvjf freetype-x.y.tar.bz2  # extract the downloaded version file
$ cd freetype-x.y/ 
$ ./configure
$ make
$ sudo make install 

切换到virtualenv并且pip install matplotlib一切正常。

This command sudo apt-get install libfreetype6-dev failed for me on ubuntu 16.04,
The following packages have unmet dependencies: libfreetype6-dev : Depends: libfreetype6 (= 2.6.1-0.1ubuntu2) but 2.6.1-0.1ubuntu2.3 is to be installed

So I downloaded installed freetype from the source, credit to this guide

$ tar -xvjf freetype-x.y.tar.bz2  # extract the downloaded version file
$ cd freetype-x.y/ 
$ ./configure
$ make
$ sudo make install 

switched to virtualenv and pip install matplotlib and everything is working.


将yerr / xerr绘制为阴影区域而不是误差线

问题:将yerr / xerr绘制为阴影区域而不是误差线

在matplotlib中,如何将错误绘制为阴影区域而不是误差线?

例如:

而不是

In matplotlib, how do I plot error as a shaded region rather than error bars?

For example:

rather than


回答 0

忽略示例图中点之间的平滑插值(这需要进行一些手动插值,或者只是具有更高的数据分辨率),可以使用pyplot.fill_between()

from matplotlib import pyplot as plt
import numpy as np

x = np.linspace(0, 30, 30)
y = np.sin(x/6*np.pi)
error = np.random.normal(0.1, 0.02, size=y.shape)
y += np.random.normal(0, 0.1, size=y.shape)

plt.plot(x, y, 'k-')
plt.fill_between(x, y-error, y+error)
plt.show()

另请参见matplotlib示例

Ignoring the smooth interpolation between points in your example graph (that would require doing some manual interpolation, or just have a higher resolution of your data), you can use pyplot.fill_between():

from matplotlib import pyplot as plt
import numpy as np

x = np.linspace(0, 30, 30)
y = np.sin(x/6*np.pi)
error = np.random.normal(0.1, 0.02, size=y.shape)
y += np.random.normal(0, 0.1, size=y.shape)

plt.plot(x, y, 'k-')
plt.fill_between(x, y-error, y+error)
plt.show()

See also the matplotlib examples.


回答 1

这基本上与Evert提供的答案相同,但扩展到展示一些很酷的选择fill_between

from matplotlib import pyplot as pl
import numpy as np

pl.clf()
pl.hold(1)

x = np.linspace(0, 30, 100)
y = np.sin(x) * 0.5
pl.plot(x, y, '-k')


x = np.linspace(0, 30, 30)
y = np.sin(x/6*np.pi)
error = np.random.normal(0.1, 0.02, size=y.shape) +.1
y += np.random.normal(0, 0.1, size=y.shape)

pl.plot(x, y, 'k', color='#CC4F1B')
pl.fill_between(x, y-error, y+error,
    alpha=0.5, edgecolor='#CC4F1B', facecolor='#FF9848')

y = np.cos(x/6*np.pi)    
error = np.random.rand(len(y)) * 0.5
y += np.random.normal(0, 0.1, size=y.shape)
pl.plot(x, y, 'k', color='#1B2ACC')
pl.fill_between(x, y-error, y+error,
    alpha=0.2, edgecolor='#1B2ACC', facecolor='#089FFF',
    linewidth=4, linestyle='dashdot', antialiased=True)



y = np.cos(x/6*np.pi)  + np.sin(x/3*np.pi)  
error = np.random.rand(len(y)) * 0.5
y += np.random.normal(0, 0.1, size=y.shape)
pl.plot(x, y, 'k', color='#3F7F4C')
pl.fill_between(x, y-error, y+error,
    alpha=1, edgecolor='#3F7F4C', facecolor='#7EFF99',
    linewidth=0)



pl.show()

This is basically the same answer provided by Evert, but extended to show-off some cool options of fill_between

from matplotlib import pyplot as pl
import numpy as np

pl.clf()
pl.hold(1)

x = np.linspace(0, 30, 100)
y = np.sin(x) * 0.5
pl.plot(x, y, '-k')


x = np.linspace(0, 30, 30)
y = np.sin(x/6*np.pi)
error = np.random.normal(0.1, 0.02, size=y.shape) +.1
y += np.random.normal(0, 0.1, size=y.shape)

pl.plot(x, y, 'k', color='#CC4F1B')
pl.fill_between(x, y-error, y+error,
    alpha=0.5, edgecolor='#CC4F1B', facecolor='#FF9848')

y = np.cos(x/6*np.pi)    
error = np.random.rand(len(y)) * 0.5
y += np.random.normal(0, 0.1, size=y.shape)
pl.plot(x, y, 'k', color='#1B2ACC')
pl.fill_between(x, y-error, y+error,
    alpha=0.2, edgecolor='#1B2ACC', facecolor='#089FFF',
    linewidth=4, linestyle='dashdot', antialiased=True)



y = np.cos(x/6*np.pi)  + np.sin(x/3*np.pi)  
error = np.random.rand(len(y)) * 0.5
y += np.random.normal(0, 0.1, size=y.shape)
pl.plot(x, y, 'k', color='#3F7F4C')
pl.fill_between(x, y-error, y+error,
    alpha=1, edgecolor='#3F7F4C', facecolor='#7EFF99',
    linewidth=0)



pl.show()

matplotlib子图的通用xlabel / ylabel

问题:matplotlib子图的通用xlabel / ylabel

我有以下情节:

fig,ax = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

现在我想给这个图提供通用的x轴标签和y轴标签。对于“ common”,我的意思是在整个子图的网格下方应有一个大的x轴标签,在右侧应有一个大的y轴标签。我在的文档中找不到关于此的任何内容plt.subplots,而我的谷歌搜索建议我需要做一个很大的工作plt.subplot(111)-但是我该如何使用5 * 2的子图将其放入其中plt.subplots呢?

I have the following plot:

fig,ax = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

and now I would like to give this plot common x-axis labels and y-axis labels. With “common”, I mean that there should be one big x-axis label below the whole grid of subplots, and one big y-axis label to the right. I can’t find anything about this in the documentation for plt.subplots, and my googlings suggest that I need to make a big plt.subplot(111) to start with – but how do I then put my 5*2 subplots into that using plt.subplots?


回答 0

这看起来像您真正想要的。它对您的特定情况采用与该答案相同的方法:

import matplotlib.pyplot as plt

fig, ax = plt.subplots(nrows=3, ncols=3, sharex=True, sharey=True, figsize=(6, 6))

fig.text(0.5, 0.04, 'common X', ha='center')
fig.text(0.04, 0.5, 'common Y', va='center', rotation='vertical')

This looks like what you actually want. It applies the same approach of this answer to your specific case:

import matplotlib.pyplot as plt

fig, ax = plt.subplots(nrows=3, ncols=3, sharex=True, sharey=True, figsize=(6, 6))

fig.text(0.5, 0.04, 'common X', ha='center')
fig.text(0.04, 0.5, 'common Y', va='center', rotation='vertical')


回答 1

由于我认为它足够相关且优雅(无需指定坐标来放置文本),因此我将其复制(稍作修改)另一个相关问题的答案

import matplotlib.pyplot as plt
fig, axes = plt.subplots(5, 2, sharex=True, sharey=True, figsize=(6,15))
# add a big axis, hide frame
fig.add_subplot(111, frameon=False)
# hide tick and tick label of the big axis
plt.tick_params(labelcolor='none', top=False, bottom=False, left=False, right=False)
plt.xlabel("common X")
plt.ylabel("common Y")

结果如下(使用matplotlib版本2.2.0):

Since I consider it relevant and elegant enough (no need to specify coordinates to place text), I copy (with a slight adaptation) an answer to another related question.

import matplotlib.pyplot as plt
fig, axes = plt.subplots(5, 2, sharex=True, sharey=True, figsize=(6,15))
# add a big axis, hide frame
fig.add_subplot(111, frameon=False)
# hide tick and tick label of the big axis
plt.tick_params(labelcolor='none', top=False, bottom=False, left=False, right=False)
plt.xlabel("common X")
plt.ylabel("common Y")

This results in the following (with matplotlib version 2.2.0):


回答 2

如果没有sharex=True, sharey=True得到:

有了它,你应该变得更好:

fig, axes2d = plt.subplots(nrows=3, ncols=3,
                           sharex=True, sharey=True,
                           figsize=(6,6))

for i, row in enumerate(axes2d):
    for j, cell in enumerate(row):
        cell.imshow(np.random.rand(32,32))

plt.tight_layout()

但是,如果要添加其他标签,则应仅将其添加到边缘图中:

fig, axes2d = plt.subplots(nrows=3, ncols=3,
                           sharex=True, sharey=True,
                           figsize=(6,6))

for i, row in enumerate(axes2d):
    for j, cell in enumerate(row):
        cell.imshow(np.random.rand(32,32))
        if i == len(axes2d) - 1:
            cell.set_xlabel("noise column: {0:d}".format(j + 1))
        if j == 0:
            cell.set_ylabel("noise row: {0:d}".format(i + 1))

plt.tight_layout()

为每个图添加标签会损坏它(也许有一种自动检测重复标签的方法,但我不知道有一个方法)。

Without sharex=True, sharey=True you get:

With it you should get it nicer:

fig, axes2d = plt.subplots(nrows=3, ncols=3,
                           sharex=True, sharey=True,
                           figsize=(6,6))

for i, row in enumerate(axes2d):
    for j, cell in enumerate(row):
        cell.imshow(np.random.rand(32,32))

plt.tight_layout()

But if you want to add additional labels, you should add them only to the edge plots:

fig, axes2d = plt.subplots(nrows=3, ncols=3,
                           sharex=True, sharey=True,
                           figsize=(6,6))

for i, row in enumerate(axes2d):
    for j, cell in enumerate(row):
        cell.imshow(np.random.rand(32,32))
        if i == len(axes2d) - 1:
            cell.set_xlabel("noise column: {0:d}".format(j + 1))
        if j == 0:
            cell.set_ylabel("noise row: {0:d}".format(i + 1))

plt.tight_layout()

Adding label for each plot would spoil it (maybe there is a way to automatically detect repeated labels, but I am not aware of one).


回答 3

由于命令:

fig,ax = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

您使用的返回一个由图和轴实例列表组成的元组,已经足够做类似的事情了(注意,我已更改fig,axfig,axes):

fig,axes = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

for ax in axes:
    ax.set_xlabel('Common x-label')
    ax.set_ylabel('Common y-label')

如果您想更改特定子图上的某些详细信息,则可以通过axes[i]在子图上进行i迭代的位置来访问它。

包含一个

fig.tight_layout()

在文件末尾的plt.show(),以避免标签重叠。

Since the command:

fig,ax = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

you used returns a tuple consisting of the figure and a list of the axes instances, it is already sufficient to do something like (mind that I’ve changed fig,axto fig,axes):

fig,axes = plt.subplots(5,2,sharex=True,sharey=True,figsize=fig_size)

for ax in axes:
    ax.set_xlabel('Common x-label')
    ax.set_ylabel('Common y-label')

If you happen to want to change some details on a specific subplot, you can access it via axes[i] where i iterates over your subplots.

It might also be very helpful to include a

fig.tight_layout()

at the end of the file, before the plt.show(), in order to avoid overlapping labels.


回答 4

如果通过在左下角为子图制作不可见的标签来保留公共标签的空间,效果会更好。从rcParams传入fontsize也很好。这样,通用标签将随rc设置而改变大小,并且还将调整轴以保留通用标签的空间。

fig_size = [8, 6]
fig, ax = plt.subplots(5, 2, sharex=True, sharey=True, figsize=fig_size)
# Reserve space for axis labels
ax[-1, 0].set_xlabel('.', color=(0, 0, 0, 0))
ax[-1, 0].set_ylabel('.', color=(0, 0, 0, 0))
# Make common axis labels
fig.text(0.5, 0.04, 'common X', va='center', ha='center', fontsize=rcParams['axes.labelsize'])
fig.text(0.04, 0.5, 'common Y', va='center', ha='center', rotation='vertical', fontsize=rcParams['axes.labelsize'])

It will look better if you reserve space for the common labels by making invisible labels for the subplot in the bottom left corner. It is also good to pass in the fontsize from rcParams. This way, the common labels will change size with your rc setup, and the axes will also be adjusted to leave space for the common labels.

fig_size = [8, 6]
fig, ax = plt.subplots(5, 2, sharex=True, sharey=True, figsize=fig_size)
# Reserve space for axis labels
ax[-1, 0].set_xlabel('.', color=(0, 0, 0, 0))
ax[-1, 0].set_ylabel('.', color=(0, 0, 0, 0))
# Make common axis labels
fig.text(0.5, 0.04, 'common X', va='center', ha='center', fontsize=rcParams['axes.labelsize'])
fig.text(0.04, 0.5, 'common Y', va='center', ha='center', rotation='vertical', fontsize=rcParams['axes.labelsize'])


回答 5

在绘制图形网格时遇到了类似的问题。图表由两部分组成(顶部和底部)。y标签应该位于两个部分的中心。

我不想使用依赖于了解外部图形中位置的解决方案(例如fig.text()),因此我操纵了set_ylabel()函数的y位置。通常为0.5,即添加到图的中间。由于代码中各部分(hspace)之间的填充为零,因此我可以计算出这两个部分相对于上部的中间位置。

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

# Create outer and inner grid
outerGrid = gridspec.GridSpec(2, 3, width_ratios=[1,1,1], height_ratios=[1,1])
somePlot = gridspec.GridSpecFromSubplotSpec(2, 1,
               subplot_spec=outerGrid[3], height_ratios=[1,3], hspace = 0)

# Add two partial plots
partA = plt.subplot(somePlot[0])
partB = plt.subplot(somePlot[1])

# No x-ticks for the upper plot
plt.setp(partA.get_xticklabels(), visible=False)

# The center is (height(top)-height(bottom))/(2*height(top))
# Simplified to 0.5 - height(bottom)/(2*height(top))
mid = 0.5-somePlot.get_height_ratios()[1]/(2.*somePlot.get_height_ratios()[0])
# Place the y-label
partA.set_ylabel('shared label', y = mid)

plt.show()

图片

缺点:

  • 到图的水平距离基于顶部,底部刻度可能延伸到标签中。

  • 该公式不考虑零件之间的空间。

  • 当顶部的高度为0时引发异常。

可能存在一个通用解决方案,其中考虑了数字之间的填充。

I ran into a similar problem while plotting a grid of graphs. The graphs consisted of two parts (top and bottom). The y-label was supposed to be centered over both parts.

I did not want to use a solution that depends on knowing the position in the outer figure (like fig.text()), so I manipulated the y-position of the set_ylabel() function. It is usually 0.5, the middle of the plot it is added to. As the padding between the parts (hspace) in my code was zero, I could calculate the middle of the two parts relative to the upper part.

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

# Create outer and inner grid
outerGrid = gridspec.GridSpec(2, 3, width_ratios=[1,1,1], height_ratios=[1,1])
somePlot = gridspec.GridSpecFromSubplotSpec(2, 1,
               subplot_spec=outerGrid[3], height_ratios=[1,3], hspace = 0)

# Add two partial plots
partA = plt.subplot(somePlot[0])
partB = plt.subplot(somePlot[1])

# No x-ticks for the upper plot
plt.setp(partA.get_xticklabels(), visible=False)

# The center is (height(top)-height(bottom))/(2*height(top))
# Simplified to 0.5 - height(bottom)/(2*height(top))
mid = 0.5-somePlot.get_height_ratios()[1]/(2.*somePlot.get_height_ratios()[0])
# Place the y-label
partA.set_ylabel('shared label', y = mid)

plt.show()

picture

Downsides:

  • The horizontal distance to the plot is based on the top part, the bottom ticks might extend into the label.

  • The formula does not take space between the parts into account.

  • Throws an exception when the height of the top part is 0.

There is probably a general solution that takes padding between figures into account.


回答 6

更新:

该功能现在是我最近在pypi上发布的proplot matplotlib软件包的一部分。默认情况下,创建图形时,标签在轴之间“共享”。


原始答案:

我发现了一个更强大的方法:

如果您知道进行初始化的bottom和和topkwargs GridSpec,或者您另外知道Figure坐标中轴的边缘位置,则还可以Figure使用一些奇特的“变换”魔术在坐标中指定ylabel位置。例如:

import matplotlib.transforms as mtransforms
bottom, top = .1, .9
f, a = plt.subplots(nrows=2, ncols=1, bottom=bottom, top=top)
avepos = (bottom+top)/2
a[0].yaxis.label.set_transform(mtransforms.blended_transform_factory(
       mtransforms.IdentityTransform(), f.transFigure # specify x, y transform
       )) # changed from default blend (IdentityTransform(), a[0].transAxes)
a[0].yaxis.label.set_position((0, avepos))
a[0].set_ylabel('Hello, world!')

…并且您应该看到标签仍然像往常一样适当地左右调整以免与刻度标签重叠-但现在它将调整为始终精确地位于所需的子图之间

此外,如果您甚至不使用set_positionylabel,则默认情况下,它会恰好显示在图形的中间。我猜这是因为最后绘制标签时matplotlib,对y-coordinate 使用0.5 而不检查基础坐标转换是否已更改。

Update:

This feature is now part of the proplot matplotlib package that I recently released on pypi. By default, when you make figures, the labels are “shared” between axes.


Original answer:

I discovered a more robust method:

If you know the bottom and top kwargs that went into a GridSpec initialization, or you otherwise know the edges positions of your axes in Figure coordinates, you can also specify the ylabel position in Figure coordinates with some fancy “transform” magic. For example:

import matplotlib.transforms as mtransforms
bottom, top = .1, .9
f, a = plt.subplots(nrows=2, ncols=1, bottom=bottom, top=top)
avepos = (bottom+top)/2
a[0].yaxis.label.set_transform(mtransforms.blended_transform_factory(
       mtransforms.IdentityTransform(), f.transFigure # specify x, y transform
       )) # changed from default blend (IdentityTransform(), a[0].transAxes)
a[0].yaxis.label.set_position((0, avepos))
a[0].set_ylabel('Hello, world!')

…and you should see that the label still appropriately adjusts left-right to keep from overlapping with ticklabels, just like normal — but now it will adjust to be always exactly between the desired subplots.

Furthermore, if you don’t even use set_position, the ylabel will show up by default exactly halfway up the figure. I’m guessing this is because when the label is finally drawn, matplotlib uses 0.5 for the y-coordinate without checking whether the underlying coordinate transform has changed.


使用Twiny时,Python Matplotlib图形标题与轴标签重叠

问题:使用Twiny时,Python Matplotlib图形标题与轴标签重叠

我正在尝试使用twiny在同一张图上绘制两个单独的数量,如下所示:

fig = figure()
ax = fig.add_subplot(111)
ax.plot(T, r, 'b-', T, R, 'r-', T, r_geo, 'g-')
ax.set_yscale('log')
ax.annotate('Approx. sea level', xy=(Planet.T_day*1.3,(Planet.R)/1000), xytext=(Planet.T_day*1.3, Planet.R/1000))
ax.annotate('Geostat. orbit', xy=(Planet.T_day*1.3, r_geo[0]), xytext=(Planet.T_day*1.3, r_geo[0]))
ax.set_xlabel('Rotational period (hrs)')
ax.set_ylabel('Orbital radius (km), logarithmic')
ax.set_title('Orbital charts for ' + Planet.N, horizontalalignment='center', verticalalignment='top')


ax2 = ax.twiny()
ax2.plot(v,r,'k-')
ax2.set_xlabel('Linear speed (ms-1)')

show()

并且数据可以很好地显示,但是我遇到的问题是,图形标题与辅助x轴上的轴标签重叠,因此几乎看不清(我想在此处发布图片示例,但是我没有足够高的代表)。

我想知道是否存在一种直接将标题直接上移几十个像素的简单方法,以使图表看起来更漂亮。

I am trying to plot two separate quantities on the same graph using twiny as follows:

fig = figure()
ax = fig.add_subplot(111)
ax.plot(T, r, 'b-', T, R, 'r-', T, r_geo, 'g-')
ax.set_yscale('log')
ax.annotate('Approx. sea level', xy=(Planet.T_day*1.3,(Planet.R)/1000), xytext=(Planet.T_day*1.3, Planet.R/1000))
ax.annotate('Geostat. orbit', xy=(Planet.T_day*1.3, r_geo[0]), xytext=(Planet.T_day*1.3, r_geo[0]))
ax.set_xlabel('Rotational period (hrs)')
ax.set_ylabel('Orbital radius (km), logarithmic')
ax.set_title('Orbital charts for ' + Planet.N, horizontalalignment='center', verticalalignment='top')


ax2 = ax.twiny()
ax2.plot(v,r,'k-')
ax2.set_xlabel('Linear speed (ms-1)')

show()

and the data is presented fine, but I am having the problem that the figure title is overlapping with the axes labels on the secondary x axis so that it’s barely legible (I wanted to post a picture example here, but I don’t have a high enough rep yet).

I’d like to know if there’s a straightforward way to just shift the title directly up a few tens of pixels, so that the chart looks prettier.


回答 0

我不确定在更高版本的matplotlib中它是否是一项新功能,但至少对于1.3.1,这很简单:

plt.title(figure_title, y=1.08)

这也适用于plt.suptitle(),但不适用于plt.xlabel(),等等。

I’m not sure whether it is a new feature in later versions of matplotlib, but at least for 1.3.1, this is simply:

plt.title(figure_title, y=1.08)

This also works for plt.suptitle(), but not (yet) for plt.xlabel(), etc.


回答 1

忘记使用plt.title并直接用放置文本plt.text。过度夸大的示例如下:

import pylab as plt

fig = plt.figure(figsize=(5,10))

figure_title = "Normal title"
ax1  = plt.subplot(1,2,1)

plt.title(figure_title, fontsize = 20)
plt.plot([1,2,3],[1,4,9])

figure_title = "Raised title"
ax2  = plt.subplot(1,2,2)

plt.text(0.5, 1.08, figure_title,
         horizontalalignment='center',
         fontsize=20,
         transform = ax2.transAxes)
plt.plot([1,2,3],[1,4,9])

plt.show()

Forget using plt.title and place the text directly with plt.text. An over-exaggerated example is given below:

import pylab as plt

fig = plt.figure(figsize=(5,10))

figure_title = "Normal title"
ax1  = plt.subplot(1,2,1)

plt.title(figure_title, fontsize = 20)
plt.plot([1,2,3],[1,4,9])

figure_title = "Raised title"
ax2  = plt.subplot(1,2,2)

plt.text(0.5, 1.08, figure_title,
         horizontalalignment='center',
         fontsize=20,
         transform = ax2.transAxes)
plt.plot([1,2,3],[1,4,9])

plt.show()


回答 2

ax.set_title('My Title\n', fontsize="15", color="red")
plt.imshow(myfile, origin="upper")

如果'\n'在标题字符串后面紧跟,则绘图将绘制在标题下方。那也可能是一个快速的解决方案。

ax.set_title('My Title\n', fontsize="15", color="red")
plt.imshow(myfile, origin="upper")

If you put '\n' right after your title string, the plot is drawn just below the title. That might be a fast solution too.


回答 3

我在x标签重叠子图标题时遇到问题;这为我工作:

import matplotlib.pyplot as plt
fig, ax = plt.subplots(2, 1)
ax[0].scatter(...)
ax[1].scatter(...)
plt.tight_layout()
.
.
.
plt.show()

之前

参考:

I was having an issue with the x-label overlapping a subplot title; this worked for me:

import matplotlib.pyplot as plt
fig, ax = plt.subplots(2, 1)
ax[0].scatter(...)
ax[1].scatter(...)
plt.tight_layout()
.
.
.
plt.show()

before

after

reference:


回答 4

只是使用plt.tight_layout()之前plt.show()。它运作良好。

Just use plt.tight_layout() before plt.show(). It works well.


回答 5

您可以在这种情况下使用pad:

ax.set_title("whatever", pad=20)

You can use pad for this case:

ax.set_title("whatever", pad=20)

如何更改情节背景颜色?

问题:如何更改情节背景颜色?

我正在matplotlib中制作散点图,需要将实际图的背景更改为黑色。我知道如何使用以下方法更改情节的脸色:

fig = plt.figure()
fig.patch.set_facecolor('xkcd:mint green')

我的问题是,这会改变情节周围空间的颜色。如何更改绘图的实际背景颜色?

I am making a scatter plot in matplotlib and need to change the background of the actual plot to black. I know how to change the face color of the plot using:

fig = plt.figure()
fig.patch.set_facecolor('xkcd:mint green')

My issue is that this changes the color of the space around the plot. How to I change the actual background color of the plot?


回答 0

使用对象set_facecolor(color)方法,axes方法是您通过以下方法之一创建的:

  • 您一起创建了图形和轴

    fig, ax = plt.subplots(nrows=1, ncols=1)
  • 您创建了一个图形,然后再创建一个轴

    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1) # nrows, ncols, index
    
  • 您使用了有状态的API(如果您要做的事情不止几行,尤其是如果您有多个绘图,则上述面向对象的方法可以简化工作,因为您可以引用特定的图形,在某些轴上进行绘图并自定义要么)

    plt.plot(...)
    ax = plt.gca()
    

然后,您可以使用set_facecolor

ax.set_facecolor('xkcd:salmon')
ax.set_facecolor((1.0, 0.47, 0.42))

作为颜色的复习:

matplotlib.colors

Matplotlib可识别以下格式以指定颜色:

  • 浮动值的RGB或RGBA元组[0, 1](例如(0.1, 0.2, 0.5)(0.1, 0.2, 0.5, 0.3));
  • 十六进制RGB或RGBA字符串(例如'#0F0F0F''#0F0F0F0F');
  • 浮点值的字符串表示形式,[0, 1]包括灰度值(例如'0.5');
  • 之一{'b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'};
  • X11 / CSS4颜色名称;
  • 来自xkcd颜色调查的名字; 前缀'xkcd:'(例如'xkcd:sky blue');
  • 其中之一{'tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan'}是“ T10”分类调色板中的Tableau颜色(这是默认颜色周期);
  • “ CN”颜色规范,即“ C”后跟一位数字,这是默认属性周期(matplotlib.rcParams['axes.prop_cycle'])的索引;该索引在艺术家创建时发生,如果循环不包含颜色,则默认为黑色。

除“ CN”外,所有颜色的字符串规格均不区分大小写。

Use the set_facecolor(color) method of the axes object, which you’ve created one of the following ways:

  • You created a figure and axis/es together

    fig, ax = plt.subplots(nrows=1, ncols=1)
    
  • You created a figure, then axis/es later

    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1) # nrows, ncols, index
    
  • You used the stateful API (if you’re doing anything more than a few lines, and especially if you have multiple plots, the object-oriented methods above make life easier because you can refer to specific figures, plot on certain axes, and customize either)

    plt.plot(...)
    ax = plt.gca()
    

Then you can use set_facecolor:

ax.set_facecolor('xkcd:salmon')
ax.set_facecolor((1.0, 0.47, 0.42))

As a refresher for what colors can be:

matplotlib.colors

Matplotlib recognizes the following formats to specify a color:

  • an RGB or RGBA tuple of float values in [0, 1] (e.g., (0.1, 0.2, 0.5) or (0.1, 0.2, 0.5, 0.3));
  • a hex RGB or RGBA string (e.g., '#0F0F0F' or '#0F0F0F0F');
  • a string representation of a float value in [0, 1] inclusive for gray level (e.g., '0.5');
  • one of {'b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'};
  • a X11/CSS4 color name;
  • a name from the xkcd color survey; prefixed with 'xkcd:' (e.g., 'xkcd:sky blue');
  • one of {'tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan'} which are the Tableau Colors from the ‘T10’ categorical palette (which is the default color cycle);
  • a “CN” color spec, i.e. ‘C’ followed by a single digit, which is an index into the default property cycle (matplotlib.rcParams['axes.prop_cycle']); the indexing occurs at artist creation time and defaults to black if the cycle does not include color.

All string specifications of color, other than “CN”, are case-insensitive.


回答 1

一种方法是在脚本中手动设置轴背景色的默认值(请参阅自定义matplotlib):

import matplotlib.pyplot as plt
plt.rcParams['axes.facecolor'] = 'black'

这与Nick T的方法相反,后者更改了特定axes对象的背景颜色。如果您要制作多个具有相似样式的不同绘图,并且不想不断更改其他axes对象,则重置默认值很有用。

注意:相当于

fig = plt.figure()
fig.patch.set_facecolor('black')

从您的问题是:

plt.rcParams['figure.facecolor'] = 'black'

One method is to manually set the default for the axis background color within your script (see Customizing matplotlib):

import matplotlib.pyplot as plt
plt.rcParams['axes.facecolor'] = 'black'

This is in contrast to Nick T’s method which changes the background color for a specific axes object. Resetting the defaults is useful if you’re making multiple different plots with similar styles and don’t want to keep changing different axes objects.

Note: The equivalent for

fig = plt.figure()
fig.patch.set_facecolor('black')

from your question is:

plt.rcParams['figure.facecolor'] = 'black'

回答 2

像这样吗 使用axisbg关键字subplot

>>> from matplotlib.figure import Figure
>>> from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
>>> figure = Figure()
>>> canvas = FigureCanvas(figure)
>>> axes = figure.add_subplot(1, 1, 1, axisbg='red')
>>> axes.plot([1,2,3])
[<matplotlib.lines.Line2D object at 0x2827e50>]
>>> canvas.print_figure('red-bg.png')

(授予的,不是散点图,也不是黑色背景。)

Something like this? Use the axisbg keyword to subplot:

>>> from matplotlib.figure import Figure
>>> from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
>>> figure = Figure()
>>> canvas = FigureCanvas(figure)
>>> axes = figure.add_subplot(1, 1, 1, axisbg='red')
>>> axes.plot([1,2,3])
[<matplotlib.lines.Line2D object at 0x2827e50>]
>>> canvas.print_figure('red-bg.png')

(Granted, not a scatter plot, and not a black background.)


回答 3

如果您已经有了axes对象,就像Nick T的答案一样,您也可以使用

 ax.patch.set_facecolor('black')

If you already have axes object, just like in Nick T‘s answer, you can also use

 ax.patch.set_facecolor('black')

回答 4

其他答案中的一个建议是使用ax.set_axis_bgcolor("red")。但是,此方法已被弃用,并且不适用于MatPlotLib> = v2.0。

还有建议使用ax.patch.set_facecolor("red")(在MatPlotLib v1.5和v2.2上均可使用)。虽然这很好用,但对于v2.0 +来说,更简单的解决方案是使用

ax.set_facecolor("red")

One suggestion in other answers is to use ax.set_axis_bgcolor("red"). This however is deprecated, and doesn’t work on MatPlotLib >= v2.0.

There is also the suggestion to use ax.patch.set_facecolor("red") (works on both MatPlotLib v1.5 & v2.2). While this works fine, an even easier solution for v2.0+ is to use

ax.set_facecolor("red")


回答 5

最简单的方法可能是在创建绘图时提供颜色:

fig1 = plt.figure(facecolor=(1, 1, 1))

要么

fig1, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, facecolor=(1, 1, 1))

The easiest thing is probably to provide the color when you create the plot :

fig1 = plt.figure(facecolor=(1, 1, 1))

or

fig1, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, facecolor=(1, 1, 1))

回答 6

比较简单的答案:

ax = plt.axes()
ax.set_facecolor('silver')

simpler answer:

ax = plt.axes()
ax.set_facecolor('silver')