标签归档:matplotlib

皮查姆不显示情节

问题:皮查姆不显示情节

Pycharm不显示以下代码中的图:

import pandas as pd
import numpy as np
import matplotlib as plt

ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))

ts = ts.cumsum()    
ts.plot()

发生的是,一个窗口出现了不到一秒钟,然后又消失了。

在图表显示的相同代码上使用Pyzo IEP IDE(使用相同的解释程序)。

…所以问题一定出在Pycharm上。我试过使用python.exe和pythonw.exe作为解释器,两者的结果相同。

这是我的sys_info:

C:\pyzo2014a\pythonw.exe -u C:\Program Files (x86)\JetBrains\PyCharm Community Edition 3.4.1\helpers\pydev\pydevconsole.py 57315 57316
PyDev console: using IPython 2.1.0import sys; print('Python %s on %s' % (sys.version, sys.platform))
Python 3.4.1 |Continuum Analytics, Inc.| (default, May 19 2014, 13:02:30) [MSC v.1600 64 bit (AMD64)] on win32
sys.path.extend(['C:\\Users\\Rasmus\\PycharmProjects\\untitled2'])
In[3]: import IPython
print(IPython.sys_info())
{'commit_hash': '681fd77',
 'commit_source': 'installation',
 'default_encoding': 'UTF-8',
 'ipython_path': 'C:\\pyzo2014a\\lib\\site-packages\\IPython',
 'ipython_version': '2.1.0',
 'os_name': 'nt',
 'platform': 'Windows-8-6.2.9200',
 'sys_executable': 'C:\\pyzo2014a\\pythonw.exe',
 'sys_platform': 'win32',
 'sys_version': '3.4.1 |Continuum Analytics, Inc.| (default, May 19 2014, '
                '13:02:30) [MSC v.1600 64 bit (AMD64)]'}

Pycharm does not show plot from the following code:

import pandas as pd
import numpy as np
import matplotlib as plt

ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))

ts = ts.cumsum()    
ts.plot()

What happens is that a window appears for less than a second, and then disappears again.

Using the Pyzo IEP IDE (using same interpreter) on the same code the plot shows as expected.

…So the problem must be with some setting on Pycharm. I’ve tried using both python.exe and pythonw.exe as interpreter both with same results.

This is my sys_info:

C:\pyzo2014a\pythonw.exe -u C:\Program Files (x86)\JetBrains\PyCharm Community Edition 3.4.1\helpers\pydev\pydevconsole.py 57315 57316
PyDev console: using IPython 2.1.0import sys; print('Python %s on %s' % (sys.version, sys.platform))
Python 3.4.1 |Continuum Analytics, Inc.| (default, May 19 2014, 13:02:30) [MSC v.1600 64 bit (AMD64)] on win32
sys.path.extend(['C:\\Users\\Rasmus\\PycharmProjects\\untitled2'])
In[3]: import IPython
print(IPython.sys_info())
{'commit_hash': '681fd77',
 'commit_source': 'installation',
 'default_encoding': 'UTF-8',
 'ipython_path': 'C:\\pyzo2014a\\lib\\site-packages\\IPython',
 'ipython_version': '2.1.0',
 'os_name': 'nt',
 'platform': 'Windows-8-6.2.9200',
 'sys_executable': 'C:\\pyzo2014a\\pythonw.exe',
 'sys_platform': 'win32',
 'sys_version': '3.4.1 |Continuum Analytics, Inc.| (default, May 19 2014, '
                '13:02:30) [MSC v.1600 64 bit (AMD64)]'}

回答 0

只需使用

plt.show()

此命令告诉系统在Pycharm中绘制图。

例:

plt.imshow(img.reshape((28, 28)))
plt.show()

Just use

plt.show()

This command tells the system to draw the plot in Pycharm.

Example:

plt.imshow(img.reshape((28, 28)))
plt.show()

回答 1

我意识到这很古老,但我想我会为其他旅客消除误解。设置plt.pyplot.isinteractive()False意味着将在特定绘制命令(即plt.pyplot.show())上绘制该图。设置plt.pyplot.isinteractive()True意味着每个pyplotplt)命令将触发绘制命令(即plt.pyplot.show())。因此,您最有可能要寻找的是plt.pyplot.show()在程序结尾处显示图形。

另外,您可以使用以下import命令(import matplotlib.pyplot as plt而不是)来缩短这些语句matplotlib as plt

I realize this is old but I figured I’d clear up a misconception for other travelers. Setting plt.pyplot.isinteractive() to False means that the plot will on be drawn on specific commands to draw (i.e. plt.pyplot.show()). Setting plt.pyplot.isinteractive() to True means that every pyplot (plt) command will trigger a draw command (i.e. plt.pyplot.show()). So what you were more than likely looking for is plt.pyplot.show() at the end of your program to display the graph.

As a side note you can shorten these statements a bit by using the following import command import matplotlib.pyplot as plt rather than matplotlib as plt.


回答 2

我有同样的问题。检查是否plt.isinteractive()为真。将其设置为“ False”对我有所帮助。

plt.interactive(False)

I had the same problem. Check wether plt.isinteractive() is True. Setting it to ‘False’ helped for me.

plt.interactive(False)

回答 3

我尝试了不同的解决方案,但最终对我有用的是plt.show(block=True)。您需要在命令之后添加此命令,此myDataFrame.plot()命令才能生效。如果您有多个绘图,只需在代码末尾添加命令。它将允许您查看正在绘制的每个数据。

I tried different solutions but what finally worked for me was plt.show(block=True). You need to add this command after the myDataFrame.plot() command for this to take effect. If you have multiple plot just add the command at the end of your code. It will allow you to see every data you are plotting.


回答 4

import matplotlib
matplotlib.use('TkAgg')

为我工作。(PyCharm / OSX)

import matplotlib
matplotlib.use('TkAgg')

Works for me. (PyCharm/OSX)


回答 5

我在Pycharm版本(社区版2017.2.2)中进行了测试,您可能需要同时声明plt.interactive(False)和plt.show(block = True),如下所示:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 6.28, 100)

plt.plot(x, x**0.5, label='square root')
plt.plot(x, np.sin(x), label='sinc')

plt.xlabel('x label')
plt.ylabel('y label')

plt.title("test plot")

plt.legend()

plt.show(block=True)
plt.interactive(False)

I test in my version of Pycharm (Community Edition 2017.2.2), you may need to announce both plt.interactive(False) and plt.show(block=True) as following:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 6.28, 100)

plt.plot(x, x**0.5, label='square root')
plt.plot(x, np.sin(x), label='sinc')

plt.xlabel('x label')
plt.ylabel('y label')

plt.title("test plot")

plt.legend()

plt.show(block=True)
plt.interactive(False)

回答 6

我找到了解决方案。这对我有用:

import numpy as np
import matplotlib.pyplot as plt

points = np.arange(-5, 5, 0.01)
dx, dy = np.meshgrid(points, points)
z = (np.sin(dx)+np.sin(dy))
plt.imshow(z)
plt.colorbar()
plt.title('plot for sin(x)+sin(y)')
plt.show()

I have found a solution. This worked for me:

import numpy as np
import matplotlib.pyplot as plt

points = np.arange(-5, 5, 0.01)
dx, dy = np.meshgrid(points, points)
z = (np.sin(dx)+np.sin(dy))
plt.imshow(z)
plt.colorbar()
plt.title('plot for sin(x)+sin(y)')
plt.show()

回答 7

调用后不久

plt.imshow() 

呼叫

plt.show(block = True)

您将获得带有图像的matplotlib弹出窗口。

这是一种阻止方式。在弹出窗口关闭之前,其他脚本将无法运行。

Soon after calling

plt.imshow() 

call

plt.show(block = True)

You will get the matplotlib popup with the image.

This is a blocking way. Further script will not run until the pop is closed.


回答 8

对于我来说,问题是matplotlib使用了错误的后端。我正在使用Debian Jessie。

在控制台中,我执行了以下操作:

import matplotlib
matplotlib.get_backend()

结果是:“ agg”,而应该是“ TkAgg”。

解决方案很简单:

  1. 通过pip卸载matplotlib
  2. 安装适当的库:sudo apt-get install tcl-dev tk-dev python-tk python3-tk
  3. 再次通过pip安装matplotlib。

With me the problem was the fact that matplotlib was using the wrong backend. I am using Debian Jessie.

In a console I did the following:

import matplotlib
matplotlib.get_backend()

The result was: ‘agg’, while this should be ‘TkAgg’.

The solution was simple:

  1. Uninstall matplotlib via pip
  2. Install the appropriate libraries: sudo apt-get install tcl-dev tk-dev python-tk python3-tk
  3. Install matplotlib via pip again.

回答 9

只需添加 plt.pyplot.show(),就可以了。

最好的解决方案是禁用SciView。

Just add plt.pyplot.show(), that would be fine.

The best solution is disabling SciView.


回答 10

我在PyCharm 2017.1.2上的版本中进行了测试。我使用交互式(True)和显示(block = True)。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1//2000',periods=1000))
ts = ts.cumsum()
plt.interactive(True)
ts.plot()
plt.show(block=True)

I tested in my version on PyCharm 2017.1.2. I used interactive (True) and show (block=True).

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1//2000',periods=1000))
ts = ts.cumsum()
plt.interactive(True)
ts.plot()
plt.show(block=True)

回答 11

以上都不对我有用,但以下内容对我有用:

  1. 禁用pycharm中的复选框(在工具窗口中显示图)settings > Tools > Python Scientific

  2. 我收到了错误消息No PyQt5 module found。继续使用以下内容的安装PyQt5

    sudo apt-get install python3-pyqt5

请注意,仅第一步就足够了并且可以工作。

None of the above worked for me but the following did:

  1. Disable the checkbox (Show plots in tool window) in pycharm settings > Tools > Python Scientific.

  2. I received the error No PyQt5 module found. Went ahead with the installation of PyQt5 using :

    sudo apt-get install python3-pyqt5
    

Beware that for some only first step is enough and works.


回答 12

我的环境:macOS和anaconda3

这对我有用:

matplotlib.use('macosx')

或互动模式:

matplotlib.use('TkAgg')

My env: macOS & anaconda3

This works for me:

matplotlib.use('macosx')

or interactive mode:

matplotlib.use('TkAgg')

回答 13

我有这个问题,我可以解决,您可以测试一下自己的方法..从设置->工具-> python科学中禁用“在工具窗口中显示图”

i had this problem and i could solve it , you can test my way.. disable “show plots in tool window” from setting–>tools–>python scientific


回答 14

DanT的评论为我解决了这个问题,在带有GTKagg后端的linux上用pycharm修复了matplotlib。导入matplotlib时,我将得到以下错误:

>>> import matplotlib as mpl

Backend GTKAgg is interactive backend. Turning interactive mode on.
Failed to enable GUI event loop integration for 'gtk'

当绘制这样的东西时:

from matplotlib import pyplot as plt
plt.figure()
plt.plot(1,2)
plt.show()

将弹出一个图形屏幕,但没有图表出现。使用:

plt.show(block=True)

正确显示图形。

Comment from DanT fixed this for me, matplotlib with pycharm on linux with the GTKagg backend. Upon importing matplotlib I would get the following error:

>>> import matplotlib as mpl

Backend GTKAgg is interactive backend. Turning interactive mode on.
Failed to enable GUI event loop integration for 'gtk'

When plotting something like so:

from matplotlib import pyplot as plt
plt.figure()
plt.plot(1,2)
plt.show()

A figure screen would pop up but no charts appear. using:

plt.show(block=True)

displays the graphic correctly.


回答 15

就我而言,我想执行以下操作:

    plt.bar(range(len(predictors)), scores)
    plt.xticks(range(len(predictors)), predictors, rotation='vertical')
    plt.show()

在这里混合了各种解决方案之后,我的解决方案是在此之前添加以下命令:

    matplotlib.get_backend()
    plt.interactive(False)
    plt.figure()

以下两种进口

   import matplotlib
   import matplotlib.pyplot as plt

在我的情况下,似乎所有命令都是必需的,带有ElCapitan和PyCharm 2016.2.3的MBP。问候!

In my case, I wanted to do the following:

    plt.bar(range(len(predictors)), scores)
    plt.xticks(range(len(predictors)), predictors, rotation='vertical')
    plt.show()

Following a mix of the solutions here, my solution was to add before that the following commands:

    matplotlib.get_backend()
    plt.interactive(False)
    plt.figure()

with the following two imports

   import matplotlib
   import matplotlib.pyplot as plt

It seems that all the commands are necessary in my case, with a MBP with ElCapitan and PyCharm 2016.2.3. Greetings!


回答 16

对于初学者,您可能还需要确保正在控制台运行脚本,而不是常规Python代码。突出显示一段代码并运行它是很容易的。

For beginners, you might also want to make sure you are running your script in the console, and not as regular Python code. It is fairly easy to highlight a piece of code and run it.


回答 17

在非交互式环境中,我们必须使用plt.show(block = True)

In non-interactive env, we have to use plt.show(block=True)


回答 18

对于那些在IDE内运行脚本(并且不能在python控制台或笔记本之类的交互式环境中工作)的人,我发现这是最直观,最简单的解决方案:

plt.imshow(img)
plt.waitforbuttonpress()

它显示了该图,并一直等到用户单击新窗口。只有这样,它才能恢复脚本并运行其余代码。

For those who are running a script inside an IDE (and not working in an interactive environment such as a python console or a notebook), I found this to be the most intuitive and the simplest solution:

plt.imshow(img)
plt.waitforbuttonpress()

It shows the figure and waits until the user clicks on the new window. Only then it resume the script and run the rest of the code.


回答 19

我能够得到这里的一些其他建议为我工作的组合,但只有当拨动plt.interactive(False)True,然后再返回。

plt.interactive(True)
plt.pyplot.show()

这将刷新我的情节。然后设置为False允许查看。

plt.interactive(False)
plt.pyplot.show()

如前所述,在关闭所有窗口之前,我的程序也不会退出。以下是有关当前运行环境的一些详细信息:

Python version 2.7.6
Anaconda 1.9.2 (x86_64)
(default, Jan 10 2014, 11:23:15) 
[GCC 4.0.1 (Apple Inc. build 5493)]
Pandas version: 0.13.1

I was able to get a combination of some of the other suggestions here working for me, but only while toggling the plt.interactive(False) to True and back again.

plt.interactive(True)
plt.pyplot.show()

This will flash up the my plots. Then setting to False allowed for viewing.

plt.interactive(False)
plt.pyplot.show()

As noted also my program would not exit until all the windows were closed. Here are some details on my current run environment:

Python version 2.7.6
Anaconda 1.9.2 (x86_64)
(default, Jan 10 2014, 11:23:15) 
[GCC 4.0.1 (Apple Inc. build 5493)]
Pandas version: 0.13.1

回答 20

需要为pycharm设置一个属性。

import matplotlib.pyplot as plt

plt.interactive(False)  #need to set to False

dataset.plot(kind='box', subplots=True, layout=(2,2), sharex=False, sharey=False)

plt.show()

One property need to set for pycharm.

import matplotlib.pyplot as plt

plt.interactive(False)  #need to set to False

dataset.plot(kind='box', subplots=True, layout=(2,2), sharex=False, sharey=False)

plt.show()

回答 21

将导入更改为:

import matplotlib.pyplot as plt

或使用此行:

plt.pyplot.show()

Change import to:

import matplotlib.pyplot as plt

or use this line:

plt.pyplot.show()

回答 22

我正在使用Ubuntu,并且按上面的@Arie所述尝试过,但是仅在终端中使用以下行:

sudo apt-get install tcl-dev tk-dev python-tk python3-tk

而且有效!

I’m using Ubuntu and I tried as @Arie said above but with this line only in terminal:

sudo apt-get install tcl-dev tk-dev python-tk python3-tk

And it worked!


回答 23

在Pycharm中,有时Matplotlib.plot不会显示。

因此,调用后plt.show(),在右侧工具栏中检查SciView。在SciView内部,将存储每个生成的图。

In Pycharm , at times the Matplotlib.plot won’t show up.

So after calling plt.show() check in the right side toolbar for SciView. Inside SciView every generated plots will be stored.


回答 24

我在尝试绘制直方图时遇到上面的错误,而下面的点对我有用。

操作系统:Mac Catalina 10.15.5

Pycharm版本:社区版本2019.2.3

Python版本:3.7

  1. 我将导入语句更改如下(从-到)

来自:

import matplotlib.pylab as plt

至:

import matplotlib.pyplot as plt

  1. 和下面的绘图语句(将我的命令表pyplot更改为plt)

从:

plt.pyplot.hist(df["horsepower"])

# set x/y labels and plot title
plt.pyplot.xlabel("horsepower")
plt.pyplot.ylabel("count")
plt.pyplot.title("horsepower bins") 

至 :

plt.hist(df["horsepower"])

# set x/y labels and plot title
plt.xlabel("horsepower")
plt.ylabel("count")
plt.title("horsepower bins")
  1. 使用plt.show显示直方图

plt.show()

I was facing above error when i am trying to plot histogram and below points worked for me.

OS : Mac Catalina 10.15.5

Pycharm Version : Community version 2019.2.3

Python version : 3.7

  1. I changed import statement as below (from – to)

from :

import matplotlib.pylab as plt

to:

import matplotlib.pyplot as plt

  1. and plot statement to below (changed my command form pyplot to plt)

from:

plt.pyplot.hist(df["horsepower"])

# set x/y labels and plot title
plt.pyplot.xlabel("horsepower")
plt.pyplot.ylabel("count")
plt.pyplot.title("horsepower bins") 

to :

plt.hist(df["horsepower"])

# set x/y labels and plot title
plt.xlabel("horsepower")
plt.ylabel("count")
plt.title("horsepower bins")
  1. use plt.show to display histogram

plt.show()


为什么用Matplotlib绘制这么慢?

问题:为什么用Matplotlib绘制这么慢?

我目前正在评估其他python绘图库。现在,我正在尝试使用matplotlib,但对性能却感到非常失望。下面的例子是从SciPy例子中修改而来的,每秒只能给我约8帧!

有什么方法可以加快速度,还是应该选择其他绘图库?

from pylab import *
import time

ion()
fig = figure()
ax1 = fig.add_subplot(611)
ax2 = fig.add_subplot(612)
ax3 = fig.add_subplot(613)
ax4 = fig.add_subplot(614)
ax5 = fig.add_subplot(615)
ax6 = fig.add_subplot(616)

x = arange(0,2*pi,0.01)
y = sin(x)
line1, = ax1.plot(x, y, 'r-')
line2, = ax2.plot(x, y, 'g-')
line3, = ax3.plot(x, y, 'y-')
line4, = ax4.plot(x, y, 'm-')
line5, = ax5.plot(x, y, 'k-')
line6, = ax6.plot(x, y, 'p-')

# turn off interactive plotting - speeds things up by 1 Frame / second
plt.ioff()


tstart = time.time()               # for profiling
for i in arange(1, 200):
    line1.set_ydata(sin(x+i/10.0))  # update the data
    line2.set_ydata(sin(2*x+i/10.0))
    line3.set_ydata(sin(3*x+i/10.0))
    line4.set_ydata(sin(4*x+i/10.0))
    line5.set_ydata(sin(5*x+i/10.0))
    line6.set_ydata(sin(6*x+i/10.0))
    draw()                         # redraw the canvas

print 'FPS:' , 200/(time.time()-tstart)

I’m currently evaluating different python plotting libraries. Right now I’m trying matplotlib and I’m quite disappointed with the performance. The following example is modified from SciPy examples and gives me only ~ 8 frames per second!

Any ways of speeding this up or should I pick a different plotting library?

from pylab import *
import time

ion()
fig = figure()
ax1 = fig.add_subplot(611)
ax2 = fig.add_subplot(612)
ax3 = fig.add_subplot(613)
ax4 = fig.add_subplot(614)
ax5 = fig.add_subplot(615)
ax6 = fig.add_subplot(616)

x = arange(0,2*pi,0.01)
y = sin(x)
line1, = ax1.plot(x, y, 'r-')
line2, = ax2.plot(x, y, 'g-')
line3, = ax3.plot(x, y, 'y-')
line4, = ax4.plot(x, y, 'm-')
line5, = ax5.plot(x, y, 'k-')
line6, = ax6.plot(x, y, 'p-')

# turn off interactive plotting - speeds things up by 1 Frame / second
plt.ioff()


tstart = time.time()               # for profiling
for i in arange(1, 200):
    line1.set_ydata(sin(x+i/10.0))  # update the data
    line2.set_ydata(sin(2*x+i/10.0))
    line3.set_ydata(sin(3*x+i/10.0))
    line4.set_ydata(sin(4*x+i/10.0))
    line5.set_ydata(sin(5*x+i/10.0))
    line6.set_ydata(sin(6*x+i/10.0))
    draw()                         # redraw the canvas

print 'FPS:' , 200/(time.time()-tstart)

回答 0

首先,(尽管这根本不会改变性能)考虑清理代码,类似于:

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

x = np.arange(0, 2*np.pi, 0.01)
y = np.sin(x)

fig, axes = plt.subplots(nrows=6)
styles = ['r-', 'g-', 'y-', 'm-', 'k-', 'c-']
lines = [ax.plot(x, y, style)[0] for ax, style in zip(axes, styles)]

fig.show()

tstart = time.time()
for i in xrange(1, 20):
    for j, line in enumerate(lines, start=1):
        line.set_ydata(np.sin(j*x + i/10.0))
    fig.canvas.draw()

print 'FPS:' , 20/(time.time()-tstart)

在上面的示例中,我得到了大约10fps。

简要说明一下,根据您的实际使用情况,matplotlib可能不是一个不错的选择。它面向的是出版物质量的数字,而不是实时显示。

但是,您可以做很多事情来加快此示例的速度。

速度如此之慢的主要原因有两个。

1)调用会重fig.canvas.draw()所有内容。这是您的瓶颈。就您而言,您无需重新绘制诸如轴边界,刻度线标签等内容。

2)在您的情况下,有很多带有很多刻度标签的子图。这些需要很长时间才能绘制出来。

这些都可以通过使用blitting来解决。

为了高效地进行blit,您必须使用特定于后端的代码。在实践中,如果您真的担心平滑的动画,那么无论如何,通常都将matplotlib图嵌入某种gui工具包中,所以这不是什么大问题。

但是,在不了解您正在做什么的情况下,我无法为您提供帮助。

但是,有一种中立的方法可以相当快地完成它。

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

x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)

fig, axes = plt.subplots(nrows=6)

fig.show()

# We need to draw the canvas before we start animating...
fig.canvas.draw()

styles = ['r-', 'g-', 'y-', 'm-', 'k-', 'c-']
def plot(ax, style):
    return ax.plot(x, y, style, animated=True)[0]
lines = [plot(ax, style) for ax, style in zip(axes, styles)]

# Let's capture the background of the figure
backgrounds = [fig.canvas.copy_from_bbox(ax.bbox) for ax in axes]

tstart = time.time()
for i in xrange(1, 2000):
    items = enumerate(zip(lines, axes, backgrounds), start=1)
    for j, (line, ax, background) in items:
        fig.canvas.restore_region(background)
        line.set_ydata(np.sin(j*x + i/10.0))
        ax.draw_artist(line)
        fig.canvas.blit(ax.bbox)

print 'FPS:' , 2000/(time.time()-tstart)

这给了我约200fps。

为了使此操作更加方便,animations最新版本的matplotlib中提供了一个模块。

举个例子:

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

x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)

fig, axes = plt.subplots(nrows=6)

styles = ['r-', 'g-', 'y-', 'm-', 'k-', 'c-']
def plot(ax, style):
    return ax.plot(x, y, style, animated=True)[0]
lines = [plot(ax, style) for ax, style in zip(axes, styles)]

def animate(i):
    for j, line in enumerate(lines, start=1):
        line.set_ydata(np.sin(j*x + i/10.0))
    return lines

# We'd normally specify a reasonable "interval" here...
ani = animation.FuncAnimation(fig, animate, xrange(1, 200), 
                              interval=0, blit=True)
plt.show()

First off, (though this won’t change the performance at all) consider cleaning up your code, similar to this:

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

x = np.arange(0, 2*np.pi, 0.01)
y = np.sin(x)

fig, axes = plt.subplots(nrows=6)
styles = ['r-', 'g-', 'y-', 'm-', 'k-', 'c-']
lines = [ax.plot(x, y, style)[0] for ax, style in zip(axes, styles)]

fig.show()

tstart = time.time()
for i in xrange(1, 20):
    for j, line in enumerate(lines, start=1):
        line.set_ydata(np.sin(j*x + i/10.0))
    fig.canvas.draw()

print 'FPS:' , 20/(time.time()-tstart)

With the above example, I get around 10fps.

Just a quick note, depending on your exact use case, matplotlib may not be a great choice. It’s oriented towards publication-quality figures, not real-time display.

However, there are a lot of things you can do to speed this example up.

There are two main reasons why this is as slow as it is.

1) Calling fig.canvas.draw() redraws everything. It’s your bottleneck. In your case, you don’t need to re-draw things like the axes boundaries, tick labels, etc.

2) In your case, there are a lot of subplots with a lot of tick labels. These take a long time to draw.

Both these can be fixed by using blitting.

To do blitting efficiently, you’ll have to use backend-specific code. In practice, if you’re really worried about smooth animations, you’re usually embedding matplotlib plots in some sort of gui toolkit, anyway, so this isn’t much of an issue.

However, without knowing a bit more about what you’re doing, I can’t help you there.

Nonetheless, there is a gui-neutral way of doing it that is still reasonably fast.

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

x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)

fig, axes = plt.subplots(nrows=6)

fig.show()

# We need to draw the canvas before we start animating...
fig.canvas.draw()

styles = ['r-', 'g-', 'y-', 'm-', 'k-', 'c-']
def plot(ax, style):
    return ax.plot(x, y, style, animated=True)[0]
lines = [plot(ax, style) for ax, style in zip(axes, styles)]

# Let's capture the background of the figure
backgrounds = [fig.canvas.copy_from_bbox(ax.bbox) for ax in axes]

tstart = time.time()
for i in xrange(1, 2000):
    items = enumerate(zip(lines, axes, backgrounds), start=1)
    for j, (line, ax, background) in items:
        fig.canvas.restore_region(background)
        line.set_ydata(np.sin(j*x + i/10.0))
        ax.draw_artist(line)
        fig.canvas.blit(ax.bbox)

print 'FPS:' , 2000/(time.time()-tstart)

This gives me ~200fps.

To make this a bit more convenient, there’s an animations module in recent versions of matplotlib.

As an example:

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

x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)

fig, axes = plt.subplots(nrows=6)

styles = ['r-', 'g-', 'y-', 'm-', 'k-', 'c-']
def plot(ax, style):
    return ax.plot(x, y, style, animated=True)[0]
lines = [plot(ax, style) for ax, style in zip(axes, styles)]

def animate(i):
    for j, line in enumerate(lines, start=1):
        line.set_ydata(np.sin(j*x + i/10.0))
    return lines

# We'd normally specify a reasonable "interval" here...
ani = animation.FuncAnimation(fig, animate, xrange(1, 200), 
                              interval=0, blit=True)
plt.show()

回答 1

Matplotlib可以制作出色的出版物质量的图形,但是在速度上没有很好的优化。有许多Python绘图软件包在设计时都考虑了速度:

Matplotlib makes great publication-quality graphics, but is not very well optimized for speed. There are a variety of python plotting packages that are designed with speed in mind:


回答 2

首先,乔·肯顿(Joe Kington)的答案使用gui-neutral方法提供了很好的建议,您绝对应该接受他的建议(尤其是关于Blitting的建议)并将其付诸实践。有关此方法的更多信息,请阅读Matplotlib Cookbook

但是,非GUI中立(GUI偏向?)方法是加快绘图速度的关键。换句话说,后端对于绘制速度极为重要。

从matplotlib导入其他任何内容之前,请先放置以下两行:

import matplotlib
matplotlib.use('GTKAgg') 

当然,可以使用多种选项代替GTKAgg,但是根据前面提到的菜谱,这是最快的。有关更多选项,请参见有关后端的链接。

To start, Joe Kington’s answer provides very good advice using a gui-neutral approach, and you should definitely take his advice (especially about Blitting) and put it into practice. More info on this approach, read the Matplotlib Cookbook

However, the non-GUI-neutral (GUI-biased?) approach is key to speeding up the plotting. In other words, the backend is extremely important to plot speed.

Put these two lines before you import anything else from matplotlib:

import matplotlib
matplotlib.use('GTKAgg') 

Of course, there are various options to use instead of GTKAgg, but according to the cookbook mentioned before, this was the fastest. See the link about backends for more options.


回答 3

对于Joe Kington提出的第一个解决方案(.copy_from_bbox&.draw_artist&canvas.blit),我必须在fig.canvas.draw()行之后捕获背景,否则背景无效,并且得到与你提到过 如果将它放在fig.show()之后,它仍然不能像Michael Browne所建议的那样工作。

所以只要把背景线的canvas.draw():

[...]
fig.show()

# We need to draw the canvas before we start animating...
fig.canvas.draw()

# Let's capture the background of the figure
backgrounds = [fig.canvas.copy_from_bbox(ax.bbox) for ax in axes]

For the first solution proposed by Joe Kington ( .copy_from_bbox & .draw_artist & canvas.blit), I had to capture the backgrounds after the fig.canvas.draw() line, otherwise the background had no effect and I got the same result as you mentioned. If you put it after the fig.show() it still does not work as proposed by Michael Browne.

So just put the background line after the canvas.draw():

[...]
fig.show()

# We need to draw the canvas before we start animating...
fig.canvas.draw()

# Let's capture the background of the figure
backgrounds = [fig.canvas.copy_from_bbox(ax.bbox) for ax in axes]

回答 4

这可能不适用于许多人,但是我通常在Linux下操作计算机,因此默认情况下,我将matplotlib图保存为PNG和SVG。这在Linux上可以正常工作,但在Windows 7安装中(Python(x,y)或Anaconda下的MiKTeX)运行起来却慢得令人难以忍受,因此我开始添加此代码,并且在那之后一切正常:

import platform     # Don't save as SVG if running under Windows.
#
# Plot code goes here.
#
fig.savefig('figure_name.png', dpi = 200)
if platform.system() != 'Windows':
    # In my installations of Windows 7, it takes an inordinate amount of time to save
    # graphs as .svg files, so on that platform I've disabled the call that does so.
    # The first run of a script is still a little slow while everything is loaded in,
    # but execution times of subsequent runs are improved immensely.
    fig.savefig('figure_name.svg')

This may not apply to many of you, but I’m usually operating my computers under Linux, so by default I save my matplotlib plots as PNG and SVG. This works fine under Linux but is unbearably slow on my Windows 7 installations [MiKTeX under Python(x,y) or Anaconda], so I’ve taken to adding this code, and things work fine over there again:

import platform     # Don't save as SVG if running under Windows.
#
# Plot code goes here.
#
fig.savefig('figure_name.png', dpi = 200)
if platform.system() != 'Windows':
    # In my installations of Windows 7, it takes an inordinate amount of time to save
    # graphs as .svg files, so on that platform I've disabled the call that does so.
    # The first run of a script is still a little slow while everything is loaded in,
    # but execution times of subsequent runs are improved immensely.
    fig.savefig('figure_name.svg')

在matplotlib中使用图,轴或图形绘制图之间有什么区别?

问题:在matplotlib中使用图,轴或图形绘制图之间有什么区别?

当我在matplotlib,tbh中绘制图时,我有点困惑后端的处理方式,我不清楚图,轴和图形的层次结构。我阅读了文档,它很有帮助,但我仍然感到困惑…

以下代码以三种不同的方式绘制相同的图:

#creating the arrays for testing
x = np.arange(1, 100)
y = np.sqrt(x)
#1st way
plt.plot(x, y)
#2nd way
ax = plt.subplot()
ax.plot(x, y)
#3rd way
figure = plt.figure()
new_plot = figure.add_subplot(111)
new_plot.plot(x, y)

现在我的问题是-

  1. 这三种方法有什么区别,我的意思是,当调用这三种方法中的任何一种时,幕后情况是什么?

  2. 什么时候应该使用哪种方法,在这些方法上使用利弊是什么?

I’m kind of confused what is going at the backend when I draw plots in matplotlib, tbh, I’m not clear with the hierarchy of plot, axes and figure. I read the documentation and it was helpful but I’m still confused…

The below code draws the same plot in three different ways –

#creating the arrays for testing
x = np.arange(1, 100)
y = np.sqrt(x)
#1st way
plt.plot(x, y)
#2nd way
ax = plt.subplot()
ax.plot(x, y)
#3rd way
figure = plt.figure()
new_plot = figure.add_subplot(111)
new_plot.plot(x, y)

Now my question is –

  1. What is the difference between all the three, I mean what is going under the hood when any of the 3 methods are called?

  2. Which method should be used when and what are the pros and cons of using any on those?


回答 0

方法1

plt.plot(x, y)

这样一来,您只能绘制一个具有(x,y)坐标的图形。如果您只想获取一张图形,则可以使用这种方式。

方法2

ax = plt.subplot()
ax.plot(x, y)

这使您可以在同一窗口中绘制一个或多个图形。在编写时,您将仅绘制一个图形,但是可以进行如下操作:

fig1, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)

您将绘制4个图形,每个图形分别命名为ax1,ax2,ax3和ax4,但在同一窗口上。在我的示例中,此窗口将分为四个部分。

方法3

fig = plt.figure()
new_plot = fig.add_subplot(111)
new_plot.plot(x, y)

我没有使用它,但是可以找到文档。

例:

import numpy as np
import matplotlib.pyplot as plt

# Method 1 #

x = np.random.rand(10)
y = np.random.rand(10)

figure1 = plt.plot(x,y)

# Method 2 #

x1 = np.random.rand(10)
x2 = np.random.rand(10)
x3 = np.random.rand(10)
x4 = np.random.rand(10)
y1 = np.random.rand(10)
y2 = np.random.rand(10)
y3 = np.random.rand(10)
y4 = np.random.rand(10)

figure2, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
ax1.plot(x1,y1)
ax2.plot(x2,y2)
ax3.plot(x3,y3)
ax4.plot(x4,y4)

plt.show()

在此处输入图片说明 在此处输入图片说明

其他例子:

在此处输入图片说明

Method 1

plt.plot(x, y)

This lets you plot just one figure with (x,y) coordinates. If you just want to get one graphic, you can use this way.

Method 2

ax = plt.subplot()
ax.plot(x, y)

This lets you plot one or several figure(s) in the same window. As you write it, you will plot just one figure, but you can make something like this:

fig1, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)

You will plot 4 figures which are named ax1, ax2, ax3 and ax4 each one but on the same window. This window will be just divided in 4 parts with my example.

Method 3

fig = plt.figure()
new_plot = fig.add_subplot(111)
new_plot.plot(x, y)

I didn’t use it, but you can find documentation.

Example:

import numpy as np
import matplotlib.pyplot as plt

# Method 1 #

x = np.random.rand(10)
y = np.random.rand(10)

figure1 = plt.plot(x,y)

# Method 2 #

x1 = np.random.rand(10)
x2 = np.random.rand(10)
x3 = np.random.rand(10)
x4 = np.random.rand(10)
y1 = np.random.rand(10)
y2 = np.random.rand(10)
y3 = np.random.rand(10)
y4 = np.random.rand(10)

figure2, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
ax1.plot(x1,y1)
ax2.plot(x2,y2)
ax3.plot(x3,y3)
ax4.plot(x4,y4)

plt.show()

enter image description here enter image description here

Other example:

enter image description here


回答 1

对象名称

Matplotlib严格面向对象,其主要对象是图形(我发现这个名称axes有些误导,但可能只是我一个人)。

您可以将图形视为画布,通常指定其尺寸,并可能指定背景颜色等。您可以通过两种方式使用画布,图形,在其上放置其他对象(主要是,但是以及文本标签等),然后使用保存其内容savefig

你可以把中轴线作为一种瑞士军刀,一个方便的对象,提供了一个工具(例如.plot.scatter.hist等)的一切,大部分。您可以使用多种不同的方法之一在图形中放置一,二,…多个

plt接口

PLT程序接口最初是模仿MATLAB™接口,但不是从面向对象的接口确实不同,即使你不直接引用的主要对象(即数字),这些对象自动将其实例化,并且每个plt方法实质上都转换为对基础对象的方法之一的调用:例如,aplt.plot()是a hidden_axes.plot,aplt.savefig是a hidden_figure.savefig

在任何时候,您都可以使用plt.gcf和来处理这些隐藏对象plt.gca,并且当其中一个对象方法尚未移植到plt命名空间中的方法时,有时这是必需的。

我想补充一点,plt命名空间还包含许多方便的方法,可以用不同的方式实例化图形

你的例子

第一种方式

plt.plot(x, y)

在这里,您仅使用plt界面,每个图中只能使用一个,但这就是您在探索数据时想要的,这是完成工作的快速方法…

第二路

ax = plt.subplot()
ax.plot(x, y)

在这里,您可以使用plt命名空间中的便捷方法为您的axes对象指定名称(和句柄),但顺便说一句,还有一个隐藏的图形。您以后可以使用axes对象来绘制,制作直方图等,可以使用plt界面进行所有操作,但是您还可以访问其所有属性并以更大的自由度对其进行修改。

第三种方式

figure = plt.figure()
new_plot = figure.add_subplot(111)
new_plot.plot(x, y)

在这里,您开始使用plt命名空间中的便捷方法实例化图形,然后仅使用面向对象的接口。

可以绕过plt便捷方法(matplotlib.figure.Figure),但是您必须调整图形以获得更好的交互体验(毕竟,这是一种便捷方法)。

个人推荐

我建议在交互式会话的环境中使用裸露plt.plotplt.scatter可能使用IPython及其%matplotlib魔术命令,也建议在探索性的Jupyter笔记本环境中使用。

另一方面,面向对象的方法以及一些plt 便捷的方法是必经之路

  • 如果您有一个永久性的问题,可以通过微调的子图的自定义安排彻底解决所有问题,
  • 如果要将Matplotlib嵌入在编写的程序的UI中。

这些极端之间有一个很大的灰色区域,如果您问我该怎么办,我只会说“这取决于”

The names of objects

Matplotlib is strongly object oriented and its principal objects are the figure and the axes (I find the name axes a bit misleading, but probably it’s just me).

You can think of the figure as a canvas, of which you typically specify the dimensions and possibly e.g., the background color etc etc. You use the canvas, the figure, essentially in two ways, placing other objects on it (mostly axes, but also text labels etc) and saving its contents with savefig.

You can think of an axes as a sort of Swiss Army knife, a handy object that offers a tool (e.g. .plot, .scatter, .hist etc) for everything, mostly. You can place one, two, … many axes inside a figure using one of many different methods.

The plt interface

The plt procedural interface was originally developed to mimic the MATLAB™ interface but is not really different from the object oriented interface, even if you don’t make a direct reference to the main objects (i.e., a figure and an axes) these objects are automatically instantiated and each plt method is, essentially, translated to a call of one of the methods of the underlying fundamental objects: e.g., a plt.plot() is a hidden_axes.plot and a plt.savefig is a hidden_figure.savefig.

In every moment you can have an handle on these hidden objects using plt.gcf and plt.gca, and this is sometimes necessary when one of the object methods has not been ported to a method in the plt namespace.

I’d like to add that the plt namespace contains also a number of convenience methods to instantiate, in different ways, figure and axes.

Your examples

1st way

plt.plot(x, y)

Here you use only the plt interface, you can only use a single axes in each figure, but this is what you want when you are doing an exploration of your data, a quick recipe that gets the work done…

2nd way

ax = plt.subplot()
ax.plot(x, y)

Here you use a convenience method in the plt namespace to give a name (and a handle) to your axes object, but btw there is also an hidden figure. You can later use the axes object to plot, to make an histogram etc, all things that you can do with the plt interface, but you can also access all its attributes and modify them with greater freedom.

3rd way

figure = plt.figure()
new_plot = figure.add_subplot(111)
new_plot.plot(x, y)

Here you start instantiating a figure using a convenience method in the plt namespace and later you use only the object oriented interface.

It is possible to bypass the plt convenience method (matplotlib.figure.Figure) but you then have to tweak the figure for a better interactive experience (after all, it’s a convenience method).

Personal recommendations

I suggest bare plt.plot, plt.scatter in the context of an interactive session, possibly using IPython with its %matplotlib magic command, and also in the context of an exploratory Jupyter notebook.

On the other hand the object oriented approach, plus a few plt convenience methods, is the way to go

  • if you have a permanent issue to solve once for all with a customized arrangement of finely tuned subplots,
  • if you want to embed Matplotlib in the UI of a program you write.

There is a large gray area between these extremes and if you ask me what to do I’d just say “It depends”


如何在Pandas barplot中旋转x轴刻度标签

问题:如何在Pandas barplot中旋转x轴刻度标签

使用以下代码:

import matplotlib
matplotlib.style.use('ggplot')
import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame({ 'celltype':["foo","bar","qux","woz"], 's1':[5,9,1,7], 's2':[12,90,13,87]})
df = df[["celltype","s1","s2"]]
df.set_index(["celltype"],inplace=True)
df.plot(kind='bar',alpha=0.75)
plt.xlabel("")

我做了这个情节:

在此处输入图片说明

如何将x轴刻度标签旋转到0度?

我尝试添加它,但是没有用:

plt.set_xticklabels(df.index,rotation=90)

With the following code:

import matplotlib
matplotlib.style.use('ggplot')
import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame({ 'celltype':["foo","bar","qux","woz"], 's1':[5,9,1,7], 's2':[12,90,13,87]})
df = df[["celltype","s1","s2"]]
df.set_index(["celltype"],inplace=True)
df.plot(kind='bar',alpha=0.75)
plt.xlabel("")

I made this plot:

enter image description here

How can I rotate the x-axis tick labels to 0 degrees?

I tried adding this but did not work:

plt.set_xticklabels(df.index,rotation=90)

回答 0

传递参数rot=0以旋转xticks:

import matplotlib
matplotlib.style.use('ggplot')
import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame({ 'celltype':["foo","bar","qux","woz"], 's1':[5,9,1,7], 's2':[12,90,13,87]})
df = df[["celltype","s1","s2"]]
df.set_index(["celltype"],inplace=True)
df.plot(kind='bar',alpha=0.75, rot=0)
plt.xlabel("")
plt.show()

Yield图:

在此处输入图片说明

Pass param rot=0 to rotate the xticks:

import matplotlib
matplotlib.style.use('ggplot')
import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame({ 'celltype':["foo","bar","qux","woz"], 's1':[5,9,1,7], 's2':[12,90,13,87]})
df = df[["celltype","s1","s2"]]
df.set_index(["celltype"],inplace=True)
df.plot(kind='bar',alpha=0.75, rot=0)
plt.xlabel("")
plt.show()

yields plot:

enter image description here


回答 1

尝试这个 –

plt.xticks(rotation=90)

在此处输入图片说明

Try this –

plt.xticks(rotation=90)

enter image description here


回答 2

问题很明确,但标题不够准确。我的答案是给那些想要更改标签(而不是刻度标签)的人的,这是公认的答案。(标题现已更正)。

for ax in plt.gcf().axes:
    plt.sca(ax)
    plt.xlabel(ax.get_xlabel(), rotation=90)

The question is clear but the title is not as precise as it could be. My answer is for those who came looking to change the axis label, as opposed to the tick labels, which is what the accepted answer is about. (The title has now been corrected).

for ax in plt.gcf().axes:
    plt.sca(ax)
    plt.xlabel(ax.get_xlabel(), rotation=90)

回答 3

您可以使用set_xticklabels()

ax.set_xticklabels(df['Names'], rotation=90, ha='right')

You can use set_xticklabels()

ax.set_xticklabels(df['Names'], rotation=90, ha='right')

回答 4

以下内容可能会有所帮助:

# Valid font size are xx-small, x-small, small, medium, large, x-large, xx-large, larger, smaller, None

plt.xticks(
    rotation=45,
    horizontalalignment='right',
    fontweight='light',
    fontsize='medium',
)

这是带有示例和API的函数xticks[reference]

def xticks(ticks=None, labels=None, **kwargs):
    """
    Get or set the current tick locations and labels of the x-axis.

    Call signatures::

        locs, labels = xticks()            # Get locations and labels
        xticks(ticks, [labels], **kwargs)  # Set locations and labels

    Parameters
    ----------
    ticks : array_like
        A list of positions at which ticks should be placed. You can pass an
        empty list to disable xticks.

    labels : array_like, optional
        A list of explicit labels to place at the given *locs*.

    **kwargs
        :class:`.Text` properties can be used to control the appearance of
        the labels.

    Returns
    -------
    locs
        An array of label locations.
    labels
        A list of `.Text` objects.

    Notes
    -----
    Calling this function with no arguments (e.g. ``xticks()``) is the pyplot
    equivalent of calling `~.Axes.get_xticks` and `~.Axes.get_xticklabels` on
    the current axes.
    Calling this function with arguments is the pyplot equivalent of calling
    `~.Axes.set_xticks` and `~.Axes.set_xticklabels` on the current axes.

    Examples
    --------
    Get the current locations and labels:

        >>> locs, labels = xticks()

    Set label locations:

        >>> xticks(np.arange(0, 1, step=0.2))

    Set text labels:

        >>> xticks(np.arange(5), ('Tom', 'Dick', 'Harry', 'Sally', 'Sue'))

    Set text labels and properties:

        >>> xticks(np.arange(12), calendar.month_name[1:13], rotation=20)

    Disable xticks:

        >>> xticks([])
    """

The follows might be helpful:

# Valid font size are xx-small, x-small, small, medium, large, x-large, xx-large, larger, smaller, None

plt.xticks(
    rotation=45,
    horizontalalignment='right',
    fontweight='light',
    fontsize='medium',
)

Here is the function xticks[reference] with example and API

def xticks(ticks=None, labels=None, **kwargs):
    """
    Get or set the current tick locations and labels of the x-axis.

    Call signatures::

        locs, labels = xticks()            # Get locations and labels
        xticks(ticks, [labels], **kwargs)  # Set locations and labels

    Parameters
    ----------
    ticks : array_like
        A list of positions at which ticks should be placed. You can pass an
        empty list to disable xticks.

    labels : array_like, optional
        A list of explicit labels to place at the given *locs*.

    **kwargs
        :class:`.Text` properties can be used to control the appearance of
        the labels.

    Returns
    -------
    locs
        An array of label locations.
    labels
        A list of `.Text` objects.

    Notes
    -----
    Calling this function with no arguments (e.g. ``xticks()``) is the pyplot
    equivalent of calling `~.Axes.get_xticks` and `~.Axes.get_xticklabels` on
    the current axes.
    Calling this function with arguments is the pyplot equivalent of calling
    `~.Axes.set_xticks` and `~.Axes.set_xticklabels` on the current axes.

    Examples
    --------
    Get the current locations and labels:

        >>> locs, labels = xticks()

    Set label locations:

        >>> xticks(np.arange(0, 1, step=0.2))

    Set text labels:

        >>> xticks(np.arange(5), ('Tom', 'Dick', 'Harry', 'Sally', 'Sue'))

    Set text labels and properties:

        >>> xticks(np.arange(12), calendar.month_name[1:13], rotation=20)

    Disable xticks:

        >>> xticks([])
    """

回答 5

对于条形图,可以包括最终希望刻度线具有的角度。

在这里,我正在rot=0使它们平行于x轴。

series.plot.bar(rot=0)
plt.show()
plt.close()

For bar graphs, you can include the angle which you finally want the ticks to have.

Here I am using rot=0 to make them parallel to the x axis.

series.plot.bar(rot=0)
plt.show()
plt.close()

如何在Python的绘图上绘制网格?[关闭]

问题:如何在Python的绘图上绘制网格?[关闭]

我刚刚完成编写代码以在python中使用pylab进行绘图,现在我想将10×10的网格叠加到散点图上。我怎么做?

我当前的代码如下:

x = numpy.arange(0, 1, 0.05)
y = numpy.power(x, 2)

fig = plt.figure()
ax = fig.gca()
ax.set_xticks(numpy.arange(0, 1, 0.1))
ax.set_yticks(numpy.arange(0, 1., 0.1))
plt.scatter(x, y)
plt.show()

其输出为:

无网格

我想要的是以下输出:

带格

编辑:添加了一个例子,基于安德烈·索博列夫的答案

I just finished writing code to make a plot using pylab in Python and now I would like to superimpose a grid of 10×10 onto the scatter plot. How do I do that?

My current code is the following:

x = numpy.arange(0, 1, 0.05)
y = numpy.power(x, 2)

fig = plt.figure()
ax = fig.gca()
ax.set_xticks(numpy.arange(0, 1, 0.1))
ax.set_yticks(numpy.arange(0, 1., 0.1))
plt.scatter(x, y)
plt.show()

And its output is:

Without grid

What I would like is the following output:

With grid

EDIT: Added an exemple, based on Andrey Sobolev’s answer


回答 0

您要使用pyplot.grid

x = numpy.arange(0, 1, 0.05)
y = numpy.power(x, 2)

fig = plt.figure()
ax = fig.gca()
ax.set_xticks(numpy.arange(0, 1, 0.1))
ax.set_yticks(numpy.arange(0, 1., 0.1))
plt.scatter(x, y)
plt.grid()
plt.show()

ax.xaxis.gridax.yaxis.grid可以控制网格线属性。

在此处输入图片说明

You want to use pyplot.grid:

x = numpy.arange(0, 1, 0.05)
y = numpy.power(x, 2)

fig = plt.figure()
ax = fig.gca()
ax.set_xticks(numpy.arange(0, 1, 0.1))
ax.set_yticks(numpy.arange(0, 1., 0.1))
plt.scatter(x, y)
plt.grid()
plt.show()

ax.xaxis.grid and ax.yaxis.grid can control grid lines properties.

Enter image description here


回答 1

要在每个刻度上显示一条网格线,请添加

plt.grid(True)

例如:

import matplotlib.pyplot as plt

points = [
    (0, 10),
    (10, 20),
    (20, 40),
    (60, 100),
]

x = list(map(lambda x: x[0], points))
y = list(map(lambda x: x[1], points))

plt.scatter(x, y)
plt.grid(True)

plt.show()

在此处输入图片说明


另外,您可能想要自定义样式(例如,实线而不是虚线),请添加:

plt.rc('grid', linestyle="-", color='black')

例如:

import matplotlib.pyplot as plt

points = [
    (0, 10),
    (10, 20),
    (20, 40),
    (60, 100),
]

x = list(map(lambda x: x[0], points))
y = list(map(lambda x: x[1], points))

plt.rc('grid', linestyle="-", color='black')
plt.scatter(x, y)
plt.grid(True)

plt.show()

在此处输入图片说明

To show a grid line on every tick, add

plt.grid(True)

For example:

import matplotlib.pyplot as plt

points = [
    (0, 10),
    (10, 20),
    (20, 40),
    (60, 100),
]

x = list(map(lambda x: x[0], points))
y = list(map(lambda x: x[1], points))

plt.scatter(x, y)
plt.grid(True)

plt.show()

enter image description here


In addition, you might want to customize the styling (e.g. solid line instead of dashed line), add:

plt.rc('grid', linestyle="-", color='black')

For example:

import matplotlib.pyplot as plt

points = [
    (0, 10),
    (10, 20),
    (20, 40),
    (60, 100),
]

x = list(map(lambda x: x[0], points))
y = list(map(lambda x: x[1], points))

plt.rc('grid', linestyle="-", color='black')
plt.scatter(x, y)
plt.grid(True)

plt.show()

enter image description here


回答 2

使用rcParams可以很容易地显示网格,如下所示

plt.rcParams['axes.facecolor'] = 'white'
plt.rcParams['axes.edgecolor'] = 'white'
plt.rcParams['axes.grid'] = True
plt.rcParams['grid.alpha'] = 1
plt.rcParams['grid.color'] = "#cccccc"

如果更改这些参数后网格仍未显示,请使用

plt.grid(True)

打电话之前

plt.show()

Using rcParams you can show grid very easily as follows

plt.rcParams['axes.facecolor'] = 'white'
plt.rcParams['axes.edgecolor'] = 'white'
plt.rcParams['axes.grid'] = True
plt.rcParams['grid.alpha'] = 1
plt.rcParams['grid.color'] = "#cccccc"

If grid is not showing even after changing these parameters then use

plt.grid(True)

before calling

plt.show()

回答 3


回答 4

这是一个小示例,说明如何使用Python 2在Gtk3中添加matplotlib网格(不适用于Python 3):

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from matplotlib.figure import Figure
from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas

win = Gtk.Window()
win.connect("delete-event", Gtk.main_quit)
win.set_title("Embedding in GTK3")

f = Figure(figsize=(1, 1), dpi=100)
ax = f.add_subplot(111)
ax.grid()

canvas = FigureCanvas(f)
canvas.set_size_request(400, 400)
win.add(canvas)

win.show_all()
Gtk.main()

在此处输入图片说明

Here is a small example how to add a matplotlib grid in Gtk3 with Python 2 (not working in Python 3):

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from matplotlib.figure import Figure
from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas

win = Gtk.Window()
win.connect("delete-event", Gtk.main_quit)
win.set_title("Embedding in GTK3")

f = Figure(figsize=(1, 1), dpi=100)
ax = f.add_subplot(111)
ax.grid()

canvas = FigureCanvas(f)
canvas.set_size_request(400, 400)
win.add(canvas)

win.show_all()
Gtk.main()

enter image description here


如何在Python中用散点图绘制散点图?

问题:如何在Python中用散点图绘制散点图?

在Python中,使用Matplotlib,如何绘制带有圆的散点图?目标是在已经由绘制的一些彩色磁盘周围绘制空圆scatter(),以便突出显示它们,理想情况下不必重新绘制彩色圆。

我试过了facecolors=None,无济于事。

In Python, with Matplotlib, how can a scatter plot with empty circles be plotted? The goal is to draw empty circles around some of the colored disks already plotted by scatter(), so as to highlight them, ideally without having to redraw the colored circles.

I tried facecolors=None, to no avail.


回答 0

从分散的文档中:

Optional kwargs control the Collection properties; in particular:

    edgecolors:
        The string none to plot faces with no outlines
    facecolors:
        The string none to plot unfilled outlines

请尝试以下操作:

import matplotlib.pyplot as plt 
import numpy as np 

x = np.random.randn(60) 
y = np.random.randn(60)

plt.scatter(x, y, s=80, facecolors='none', edgecolors='r')
plt.show()

示例图片

注意:对于其他类型的地块看到这个帖子的使用markeredgecolormarkerfacecolor

From the documentation for scatter:

Optional kwargs control the Collection properties; in particular:

    edgecolors:
        The string ‘none’ to plot faces with no outlines
    facecolors:
        The string ‘none’ to plot unfilled outlines

Try the following:

import matplotlib.pyplot as plt 
import numpy as np 

x = np.random.randn(60) 
y = np.random.randn(60)

plt.scatter(x, y, s=80, facecolors='none', edgecolors='r')
plt.show()

example image

Note: For other types of plots see this post on the use of markeredgecolor and markerfacecolor.


回答 1

这些行得通吗?

plt.scatter(np.random.randn(100), np.random.randn(100), facecolors='none')

示例图片

或使用plot()

plt.plot(np.random.randn(100), np.random.randn(100), 'o', mfc='none')

示例图片

Would these work?

plt.scatter(np.random.randn(100), np.random.randn(100), facecolors='none')

example image

or using plot()

plt.plot(np.random.randn(100), np.random.randn(100), 'o', mfc='none')

example image


回答 2

这是另一种方式:这会在当前轴,图或图像等上添加一个圆:

from matplotlib.patches import Circle  # $matplotlib/patches.py

def circle( xy, radius, color="lightsteelblue", facecolor="none", alpha=1, ax=None ):
    """ add a circle to ax= or current axes
    """
        # from .../pylab_examples/ellipse_demo.py
    e = Circle( xy=xy, radius=radius )
    if ax is None:
        ax = pl.gca()  # ax = subplot( 1,1,1 )
    ax.add_artist(e)
    e.set_clip_box(ax.bbox)
    e.set_edgecolor( color )
    e.set_facecolor( facecolor )  # "none" not None
    e.set_alpha( alpha )

替代文字

(由于,图片中的圆圈被挤压成椭圆形imshow aspect="auto")。

Here’s another way: this adds a circle to the current axes, plot or image or whatever :

from matplotlib.patches import Circle  # $matplotlib/patches.py

def circle( xy, radius, color="lightsteelblue", facecolor="none", alpha=1, ax=None ):
    """ add a circle to ax= or current axes
    """
        # from .../pylab_examples/ellipse_demo.py
    e = Circle( xy=xy, radius=radius )
    if ax is None:
        ax = pl.gca()  # ax = subplot( 1,1,1 )
    ax.add_artist(e)
    e.set_clip_box(ax.bbox)
    e.set_edgecolor( color )
    e.set_facecolor( facecolor )  # "none" not None
    e.set_alpha( alpha )

alt text

(The circles in the picture get squashed to ellipses because imshow aspect="auto" ).


回答 3

在matplotlib 2.0中,有一个名为的参数fillstyle ,可以更好地控制标记的填充方式。就我而言,我已将其与错误栏一起使用,但它可用于一般http://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.errorbar.html中的标记

fillstyle接受以下值:[‘full’| “左” | ‘正确’| “底部” | ‘顶部’| ‘没有’]

使用时有两点要牢记fillstyle

1)如果将mfc设置为任何类型的值,它将具有优先权,因此,如果您将fillstyle设置为“ none”,则它不会生效。因此,请避免同时使用mfc和fillstyle

2)您可能想要控制标记的边缘宽度(使用markeredgewidthmew),因为如果标记相对较小且边缘宽度较厚,则标记看起来会像已填充,即使没有。

以下是使用错误栏的示例:

myplot.errorbar(x=myXval, y=myYval, yerr=myYerrVal, fmt='o', fillstyle='none', ecolor='blue',  mec='blue')

In matplotlib 2.0 there is a parameter called fillstyle which allows better control on the way markers are filled. In my case I have used it with errorbars but it works for markers in general http://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.errorbar.html

fillstyle accepts the following values: [‘full’ | ‘left’ | ‘right’ | ‘bottom’ | ‘top’ | ‘none’]

There are two important things to keep in mind when using fillstyle,

1) If mfc is set to any kind of value it will take priority, hence, if you did set fillstyle to ‘none’ it would not take effect. So avoid using mfc in conjuntion with fillstyle

2) You might want to control the marker edge width (using markeredgewidth or mew) because if the marker is relatively small and the edge width is thick, the markers will look like filled even though they are not.

Following is an example using errorbars:

myplot.errorbar(x=myXval, y=myYval, yerr=myYerrVal, fmt='o', fillstyle='none', ecolor='blue',  mec='blue')

回答 4

基于Gary Kerr的示例,如此处所建议可以使用以下代码创建与指定值相关的空圆:

import matplotlib.pyplot as plt 
import numpy as np 
from matplotlib.markers import MarkerStyle

x = np.random.randn(60) 
y = np.random.randn(60)
z = np.random.randn(60)

g=plt.scatter(x, y, s=80, c=z)
g.set_facecolor('none')
plt.colorbar()
plt.show()

Basend on the example of Gary Kerr and as proposed here one may create empty circles related to specified values with following code:

import matplotlib.pyplot as plt 
import numpy as np 
from matplotlib.markers import MarkerStyle

x = np.random.randn(60) 
y = np.random.randn(60)
z = np.random.randn(60)

g=plt.scatter(x, y, s=80, c=z)
g.set_facecolor('none')
plt.colorbar()
plt.show()

回答 5

因此,我假设您想突出显示符合特定条件的一些要点。您可以使用Prelude的命令对高亮点进行第二次散点图绘制,并用一个空圆进行第一次散点图绘制。确保s参数足够小,以使较大的空圆圈包围较小的填充圆。

另一个选择是不使用散点图,而使用circle / ellipse命令分别绘制补丁。这些位于matplotlib.patches中,是一些有关如何绘制圆形矩形等的示例代码。

So I assume you want to highlight some points that fit a certain criteria. You can use Prelude’s command to do a second scatter plot of the hightlighted points with an empty circle and a first call to plot all the points. Make sure the s paramter is sufficiently small for the larger empty circles to enclose the smaller filled ones.

The other option is to not use scatter and draw the patches individually using the circle/ellipse command. These are in matplotlib.patches, here is some sample code on how to draw circles rectangles etc.


如何使用matplotlib为多个子图制作一个图例?

问题:如何使用matplotlib为多个子图制作一个图例?

我正在绘制相同类型的信息,但针对不同的国家,使用matplotlib具有多个子图。也就是说,我在3×3网格上有9个图,所有图线都相同(当然,每条线的值不同)。

但是,我还没有想出如何仅在图上放置一个图例(因为所有9个子图都有相同的行)。

我怎么做?

I am plotting the same type of information, but for different countries, with multiple subplots with matplotlib. That is, I have 9 plots on a 3×3 grid, all with the same for lines (of course, different values per line).

However, I have not figured out how to put a single legend (since all 9 subplots have the same lines) on the figure just once.

How do I do that?


回答 0

get_legend_handles_labels()您还可以在最后一个轴上调用一个不错的函数(如果对其进行迭代),该label=函数将从参数中收集所需的所有信息:

handles, labels = ax.get_legend_handles_labels()
fig.legend(handles, labels, loc='upper center')

There is also a nice function get_legend_handles_labels() you can call on the last axis (if you iterate over them) that would collect everything you need from label= arguments:

handles, labels = ax.get_legend_handles_labels()
fig.legend(handles, labels, loc='upper center')

回答 1

figlegend可能就是您要寻找的东西:http ://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.figlegend

此处的示例:http : //matplotlib.org/examples/pylab_examples/figlegend_demo.html

另一个例子:

plt.figlegend( lines, labels, loc = 'lower center', ncol=5, labelspacing=0. )

要么:

fig.legend( lines, labels, loc = (0.5, 0), ncol=5 )

figlegend may be what you’re looking for: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.figlegend

Example here: http://matplotlib.org/examples/pylab_examples/figlegend_demo.html

Another example:

plt.figlegend( lines, labels, loc = 'lower center', ncol=5, labelspacing=0. )

or:

fig.legend( lines, labels, loc = (0.5, 0), ncol=5 )

回答 2

为了自动将单个图例定位在figure具有多个轴的轴上(如通过所获得的轴),subplots()以下解决方案非常有效:

plt.legend( lines, labels, loc = 'lower center', bbox_to_anchor = (0,-0.1,1,1),
            bbox_transform = plt.gcf().transFigure )

使用bbox_to_anchor和,bbox_transform=plt.gcf().transFigure您将定义一个与您的大小相同的新边框figure作为的参考loc。使用(0,-0.1,1,1)此装订线框稍微向下移动,以防止将图例放置在其他艺术家的上方。

OBS:使用之后fig.set_size_inches()和使用之前,请使用此解决方案fig.tight_layout()

For the automatic positioning of a single legend in a figure with many axes, like those obtained with subplots(), the following solution works really well:

plt.legend( lines, labels, loc = 'lower center', bbox_to_anchor = (0,-0.1,1,1),
            bbox_transform = plt.gcf().transFigure )

With bbox_to_anchor and bbox_transform=plt.gcf().transFigure you are defining a new bounding box of the size of your figureto be a reference for loc. Using (0,-0.1,1,1) moves this bouding box slightly downwards to prevent the legend to be placed over other artists.

OBS: use this solution AFTER you use fig.set_size_inches() and BEFORE you use fig.tight_layout()


回答 3

您只需要在循环外询问一次图例。

例如,在这种情况下,我有4个子图,它们具有相同的行和一个图例。

from matplotlib.pyplot import *

ficheiros = ['120318.nc', '120319.nc', '120320.nc', '120321.nc']

fig = figure()
fig.suptitle('concentration profile analysis')

for a in range(len(ficheiros)):
    # dados is here defined
    level = dados.variables['level'][:]

    ax = fig.add_subplot(2,2,a+1)
    xticks(range(8), ['0h','3h','6h','9h','12h','15h','18h','21h']) 
    ax.set_xlabel('time (hours)')
    ax.set_ylabel('CONC ($\mu g. m^{-3}$)')

    for index in range(len(level)):
        conc = dados.variables['CONC'][4:12,index] * 1e9
        ax.plot(conc,label=str(level[index])+'m')

    dados.close()

ax.legend(bbox_to_anchor=(1.05, 0), loc='lower left', borderaxespad=0.)
         # it will place the legend on the outer right-hand side of the last axes

show()

You just have to ask for the legend once, outside of your loop.

For example, in this case I have 4 subplots, with the same lines, and a single legend.

from matplotlib.pyplot import *

ficheiros = ['120318.nc', '120319.nc', '120320.nc', '120321.nc']

fig = figure()
fig.suptitle('concentration profile analysis')

for a in range(len(ficheiros)):
    # dados is here defined
    level = dados.variables['level'][:]

    ax = fig.add_subplot(2,2,a+1)
    xticks(range(8), ['0h','3h','6h','9h','12h','15h','18h','21h']) 
    ax.set_xlabel('time (hours)')
    ax.set_ylabel('CONC ($\mu g. m^{-3}$)')

    for index in range(len(level)):
        conc = dados.variables['CONC'][4:12,index] * 1e9
        ax.plot(conc,label=str(level[index])+'m')

    dados.close()

ax.legend(bbox_to_anchor=(1.05, 0), loc='lower left', borderaxespad=0.)
         # it will place the legend on the outer right-hand side of the last axes

show()

回答 4

我注意到没有答案显示带有单个图例的图像,该图例引用了不同子图中的许多曲线,因此我必须向您展示一个……让您感到好奇……

在此处输入图片说明

现在,您想看一下代码,不是吗?

from numpy import linspace
import matplotlib.pyplot as plt

# Calling the axes.prop_cycle returns an itertoools.cycle

color_cycle = plt.rcParams['axes.prop_cycle']()

# I need some curves to plot

x = linspace(0, 1, 51)
f1 = x*(1-x)   ; lab1 = 'x - x x'
f2 = 0.25-f1   ; lab2 = '1/4 - x + x x' 
f3 = x*x*(1-x) ; lab3 = 'x x - x x x'
f4 = 0.25-f3   ; lab4 = '1/4 - x x + x x x'

# let's plot our curves (note the use of color cycle, otherwise the curves colors in
# the two subplots will be repeated and a single legend becomes difficult to read)
fig, (a13, a24) = plt.subplots(2)

a13.plot(x, f1, label=lab1, **next(color_cycle))
a13.plot(x, f3, label=lab3, **next(color_cycle))
a24.plot(x, f2, label=lab2, **next(color_cycle))
a24.plot(x, f4, label=lab4, **next(color_cycle))

# so far so good, now the trick

lines_labels = [ax.get_legend_handles_labels() for ax in fig.axes]
lines, labels = [sum(lol, []) for lol in zip(*lines_labels)]

# finally we invoke the legend (that you probably would like to customize...)

fig.legend(lines, labels)
plt.show()

两条线

lines_labels = [ax.get_legend_handles_labels() for ax in fig.axes]
lines, labels = [sum(lol, []) for lol in zip(*lines_labels)]

值得解释-为此,我将棘手的部分封装在一个函数中,仅用4行代码,但注释严重

def fig_legend(fig, **kwdargs):

    # generate a sequence of tuples, each contains
    #  - a list of handles (lohand) and
    #  - a list of labels (lolbl)
    tuples_lohand_lolbl = (ax.get_legend_handles_labels() for ax in fig.axes)
    # e.g. a figure with two axes, ax0 with two curves, ax1 with one curve
    # yields:   ([ax0h0, ax0h1], [ax0l0, ax0l1]) and ([ax1h0], [ax1l0])

    # legend needs a list of handles and a list of labels, 
    # so our first step is to transpose our data,
    # generating two tuples of lists of homogeneous stuff(tolohs), i.e
    # we yield ([ax0h0, ax0h1], [ax1h0]) and ([ax0l0, ax0l1], [ax1l0])
    tolohs = zip(*tuples_lohand_lolbl)

    # finally we need to concatenate the individual lists in the two
    # lists of lists: [ax0h0, ax0h1, ax1h0] and [ax0l0, ax0l1, ax1l0]
    # a possible solution is to sum the sublists - we use unpacking
    handles, labels = (sum(list_of_lists, []) for list_of_lists in tolohs)

    # call fig.legend with the keyword arguments, return the legend object

    return fig.legend(handles, labels, **kwdargs)

PS我认识到这sum(list_of_lists, [])是一种平整列表列表的方法,实际上是一种效率很低的方法,但是①我喜欢它的紧凑性,②通常在几个子图中有一些曲线,并且③Matplotlib和效率高吗?;-)

I have noticed that no answer display an image with a single legend referencing many curves in different subplots, so I have to show you one… to make you curious…

enter image description here

Now, you want to look at the code, don’t you?

from numpy import linspace
import matplotlib.pyplot as plt

# Calling the axes.prop_cycle returns an itertoools.cycle

color_cycle = plt.rcParams['axes.prop_cycle']()

# I need some curves to plot

x = linspace(0, 1, 51)
f1 = x*(1-x)   ; lab1 = 'x - x x'
f2 = 0.25-f1   ; lab2 = '1/4 - x + x x' 
f3 = x*x*(1-x) ; lab3 = 'x x - x x x'
f4 = 0.25-f3   ; lab4 = '1/4 - x x + x x x'

# let's plot our curves (note the use of color cycle, otherwise the curves colors in
# the two subplots will be repeated and a single legend becomes difficult to read)
fig, (a13, a24) = plt.subplots(2)

a13.plot(x, f1, label=lab1, **next(color_cycle))
a13.plot(x, f3, label=lab3, **next(color_cycle))
a24.plot(x, f2, label=lab2, **next(color_cycle))
a24.plot(x, f4, label=lab4, **next(color_cycle))

# so far so good, now the trick

lines_labels = [ax.get_legend_handles_labels() for ax in fig.axes]
lines, labels = [sum(lol, []) for lol in zip(*lines_labels)]

# finally we invoke the legend (that you probably would like to customize...)

fig.legend(lines, labels)
plt.show()

The two lines

lines_labels = [ax.get_legend_handles_labels() for ax in fig.axes]
lines, labels = [sum(lol, []) for lol in zip(*lines_labels)]

deserve an explanation — to this aim I have encapsulated the tricky part in a function, just 4 lines of code but heavily commented

def fig_legend(fig, **kwdargs):

    # generate a sequence of tuples, each contains
    #  - a list of handles (lohand) and
    #  - a list of labels (lolbl)
    tuples_lohand_lolbl = (ax.get_legend_handles_labels() for ax in fig.axes)
    # e.g. a figure with two axes, ax0 with two curves, ax1 with one curve
    # yields:   ([ax0h0, ax0h1], [ax0l0, ax0l1]) and ([ax1h0], [ax1l0])
    
    # legend needs a list of handles and a list of labels, 
    # so our first step is to transpose our data,
    # generating two tuples of lists of homogeneous stuff(tolohs), i.e
    # we yield ([ax0h0, ax0h1], [ax1h0]) and ([ax0l0, ax0l1], [ax1l0])
    tolohs = zip(*tuples_lohand_lolbl)

    # finally we need to concatenate the individual lists in the two
    # lists of lists: [ax0h0, ax0h1, ax1h0] and [ax0l0, ax0l1, ax1l0]
    # a possible solution is to sum the sublists - we use unpacking
    handles, labels = (sum(list_of_lists, []) for list_of_lists in tolohs)

    # call fig.legend with the keyword arguments, return the legend object

    return fig.legend(handles, labels, **kwdargs)

PS I recognize that sum(list_of_lists, []) is a really inefficient method to flatten a list of lists but ① I love its compactness, ② usually is a few curves in a few subplots and ③ Matplotlib and efficiency? ;-)


Important Update

If you want to stick with the official Matplotlib API my answer above is perfect, really.

On the other hand, if you don’t mind using a private method of the matplotlib.legend module … it’s really much much much easier

from matplotlib.legend import _get_legend_handles_labels
...

fig.legend(*_get_legend_handles_and_labels(fig.axes), ...)

A complete explanation can be found in the source code of Axes.get_legend_handles_labels in .../matplotlib/axes/_axes.py


回答 5

虽然游戏时间比较晚,但我将在此处提供另一种解决方案,因为这仍然是显示在Google上的第一个链接之一。使用matplotlib 2.2.2,可以使用gridspec功能来实现。在下面的示例中,目标是以2×2的方式排列四个子图,图例显示在底部。在底部创建一个“人造”轴,以将图例放置在固定位置。然后关闭“人造”轴,因此仅显示图例。结果:https : //i.stack.imgur.com/5LUWM.png

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

#Gridspec demo
fig = plt.figure()
fig.set_size_inches(8,9)
fig.set_dpi(100)

rows   = 17 #the larger the number here, the smaller the spacing around the legend
start1 = 0
end1   = int((rows-1)/2)
start2 = end1
end2   = int(rows-1)

gspec = gridspec.GridSpec(ncols=4, nrows=rows)

axes = []
axes.append(fig.add_subplot(gspec[start1:end1,0:2]))
axes.append(fig.add_subplot(gspec[start2:end2,0:2]))
axes.append(fig.add_subplot(gspec[start1:end1,2:4]))
axes.append(fig.add_subplot(gspec[start2:end2,2:4]))
axes.append(fig.add_subplot(gspec[end2,0:4]))

line, = axes[0].plot([0,1],[0,1],'b')           #add some data
axes[-1].legend((line,),('Test',),loc='center') #create legend on bottommost axis
axes[-1].set_axis_off()                         #don't show bottommost axis

fig.tight_layout()
plt.show()

While rather late to the game, I’ll give another solution here as this is still one of the first links to show up on google. Using matplotlib 2.2.2, this can be achieved using the gridspec feature. In the example below the aim is to have four subplots arranged in a 2×2 fashion with the legend shown at the bottom. A ‘faux’ axis is created at the bottom to place the legend in a fixed spot. The ‘faux’ axis is then turned off so only the legend shows. Result: https://i.stack.imgur.com/5LUWM.png.

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

#Gridspec demo
fig = plt.figure()
fig.set_size_inches(8,9)
fig.set_dpi(100)

rows   = 17 #the larger the number here, the smaller the spacing around the legend
start1 = 0
end1   = int((rows-1)/2)
start2 = end1
end2   = int(rows-1)

gspec = gridspec.GridSpec(ncols=4, nrows=rows)

axes = []
axes.append(fig.add_subplot(gspec[start1:end1,0:2]))
axes.append(fig.add_subplot(gspec[start2:end2,0:2]))
axes.append(fig.add_subplot(gspec[start1:end1,2:4]))
axes.append(fig.add_subplot(gspec[start2:end2,2:4]))
axes.append(fig.add_subplot(gspec[end2,0:4]))

line, = axes[0].plot([0,1],[0,1],'b')           #add some data
axes[-1].legend((line,),('Test',),loc='center') #create legend on bottommost axis
axes[-1].set_axis_off()                         #don't show bottommost axis

fig.tight_layout()
plt.show()

回答 6

如果您将子图与条形图一起使用,则每个条形具有不同的颜色。自己动手制作艺术品可能会更快mpatches

假设您有四个颜色不同的条形图,r m c k可以按如下所示设置图例

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
labels = ['Red Bar', 'Magenta Bar', 'Cyan Bar', 'Black Bar']


#####################################
# insert code for the subplots here #
#####################################


# now, create an artist for each color
red_patch = mpatches.Patch(facecolor='r', edgecolor='#000000') #this will create a red bar with black borders, you can leave out edgecolor if you do not want the borders
black_patch = mpatches.Patch(facecolor='k', edgecolor='#000000')
magenta_patch = mpatches.Patch(facecolor='m', edgecolor='#000000')
cyan_patch = mpatches.Patch(facecolor='c', edgecolor='#000000')
fig.legend(handles = [red_patch, magenta_patch, cyan_patch, black_patch],labels=labels,
       loc="center right", 
       borderaxespad=0.1)
plt.subplots_adjust(right=0.85) #adjust the subplot to the right for the legend

if you are using subplots with bar charts, with different colour for each bar. it may be faster to create the artefacts yourself using mpatches

Say you have four bars with different colours as r m c k you can set the legend as follows

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
labels = ['Red Bar', 'Magenta Bar', 'Cyan Bar', 'Black Bar']


#####################################
# insert code for the subplots here #
#####################################


# now, create an artist for each color
red_patch = mpatches.Patch(facecolor='r', edgecolor='#000000') #this will create a red bar with black borders, you can leave out edgecolor if you do not want the borders
black_patch = mpatches.Patch(facecolor='k', edgecolor='#000000')
magenta_patch = mpatches.Patch(facecolor='m', edgecolor='#000000')
cyan_patch = mpatches.Patch(facecolor='c', edgecolor='#000000')
fig.legend(handles = [red_patch, magenta_patch, cyan_patch, black_patch],labels=labels,
       loc="center right", 
       borderaxespad=0.1)
plt.subplots_adjust(right=0.85) #adjust the subplot to the right for the legend

回答 7

此答案是@Evert在图例位置的补充。

由于图例和子图标题的重叠,我对@Evert解决方案的首次尝试失败。

实际上,重叠是由引起的fig.tight_layout(),这会更改子图的布局而无需考虑图形图例。但是,这fig.tight_layout()是必需的。

为了避免重叠,我们可以通过告知fig.tight_layout()为人物的图例保留空格fig.tight_layout(rect=(0,0,1,0.9))

.tight_layout()参数的描述

This answer is a complement to @Evert’s on the legend position.

My first try on @Evert’s solution failed due to overlaps of the legend and the subplot’s title.

In fact, the overlaps are caused by fig.tight_layout(), which changes the subplots’ layout without considering the figure legend. However, fig.tight_layout() is necessary.

In order to avoid the overlaps, we can tell fig.tight_layout() to leave spaces for the figure’s legend by fig.tight_layout(rect=(0,0,1,0.9)).

Description of tight_layout() parameters.


回答 8

要建立在@gboffi和Ben Usman的答案之上:

在不同的子图中具有相同颜色和标签的不同线条的情况下,可以沿

labels_handles = {
  label: handle for ax in fig.axes for handle, label in zip(*ax.get_legend_handles_labels())
}

fig.legend(
  labels_handles.values(),
  labels_handles.keys(),
  loc="upper center",
  bbox_to_anchor=(0.5, 0),
  bbox_transform=plt.gcf().transFigure,
)

To build on top of @gboffi’s and Ben Usman’s answer:

In a situation where one has different lines in different subplots with the same color and label, one can do something along the lines of

labels_handles = {
  label: handle for ax in fig.axes for handle, label in zip(*ax.get_legend_handles_labels())
}

fig.legend(
  labels_handles.values(),
  labels_handles.keys(),
  loc="upper center",
  bbox_to_anchor=(0.5, 0),
  bbox_transform=plt.gcf().transFigure,
)

警告有太多未结数字

问题:警告有太多未结数字

在使用创建大量图形的脚本中fix, ax = plt.subplots(...),我收到警告RuntimeWarning:已打开20个以上图形。通过pyplot接口(matplotlib.pyplot.figure)创建的图形将保留到显式关闭,并且可能会占用过多内存。

但是,我不明白为什么会收到此警告,因为使用保存了该数字之后fig.savefig(...),我使用删除了该警告fig.clear(); del fig。在我的代码中,我一次都没有打开多个图形。不过,我仍然收到有关太多未结数字的警告。这是什么意思/如何避免收到警告?

In a script where I create many figures with fix, ax = plt.subplots(...), I get the warning RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (matplotlib.pyplot.figure) are retained until explicitly closed and may consume too much memory.

However, I don’t understand why I get this warning, because after saving the figure with fig.savefig(...), I delete it with fig.clear(); del fig. At no point in my code, I have more than one figure open at a time. Still, I get the warning about too many open figures. What does that mean / how can I avoid getting the warning?


回答 0

在图形对象上使用.clf.cla,而不要创建一个图形。来自@DavidZwicker

假设您已导入pyplot

import matplotlib.pyplot as plt

plt.cla()清除轴,即当前图形中的当前活动轴。保持其他轴不变。

plt.clf()清除所有轴的整个当前图形,但使窗口保持打开状态,以便可以将其重新用于其他图形。

plt.close()关闭一个window,如果没有另外指定,它将是当前窗口。plt.close('all')将关闭所有未结数字。

之所以del fig不起作用,是因为pyplot状态机一直在参考周围的数字(因为要知道“当前数字”是什么,就必须这样做)。这意味着即使您删除对该图引用,也至少有一个活动引用,因此将永远不会进行垃圾回收。

由于我在这里针对此答案轮询集体智慧,因此@JoeKington在评论中提到plt.close(fig)将从pylab状态机(plt._pylab_helpers.Gcf)中删除特定的图形实例,并允许对其进行垃圾回收。

Use .clf or .cla on your figure object instead of creating a new figure. From @DavidZwicker

Assuming you have imported pyplot as

import matplotlib.pyplot as plt

plt.cla() clears an axis, i.e. the currently active axis in the current figure. It leaves the other axes untouched.

plt.clf() clears the entire current figure with all its axes, but leaves the window opened, such that it may be reused for other plots.

plt.close() closes a window, which will be the current window, if not specified otherwise. plt.close('all') will close all open figures.

The reason that del fig does not work is that the pyplot state-machine keeps a reference to the figure around (as it must if it is going to know what the ‘current figure’ is). This means that even if you delete your ref to the figure, there is at least one live ref, hence it will never be garbage collected.

Since I’m polling on the collective wisdom here for this answer, @JoeKington mentions in the comments that plt.close(fig) will remove a specific figure instance from the pylab state machine (plt._pylab_helpers.Gcf) and allow it to be garbage collected.


回答 1

这是Hooked的答案的更多细节。当我第一次阅读该答案时,我错过了调用说明,clf() 而不是创建一个新图形clf()如果您自己去创建另一个图形,它本身并没有帮助。

这是一个引起警告的简单示例:

from matplotlib import pyplot as plt, patches
import os


def main():
    path = 'figures'
    for i in range(21):
        _fig, ax = plt.subplots()
        x = range(3*i)
        y = [n*n for n in x]
        ax.add_patch(patches.Rectangle(xy=(i, 1), width=i, height=10))
        plt.step(x, y, linewidth=2, where='mid')
        figname = 'fig_{}.png'.format(i)
        dest = os.path.join(path, figname)
        plt.savefig(dest)  # write image to file
        plt.clf()
    print('Done.')

main()

为了避免警告,我必须将调用拉到subplots()循环之外。为了继续看到矩形,我需要切换clf()cla()。这将清除轴,而不会移除轴本身。

from matplotlib import pyplot as plt, patches
import os


def main():
    path = 'figures'
    _fig, ax = plt.subplots()
    for i in range(21):
        x = range(3*i)
        y = [n*n for n in x]
        ax.add_patch(patches.Rectangle(xy=(i, 1), width=i, height=10))
        plt.step(x, y, linewidth=2, where='mid')
        figname = 'fig_{}.png'.format(i)
        dest = os.path.join(path, figname)
        plt.savefig(dest)  # write image to file
        plt.cla()
    print('Done.')

main()

如果要批量生成图,则可能必须同时使用cla()close()。我遇到了一个问题,即一个批次可以拥有20多个地块而没有抱怨,但在20批次之后它会抱怨。我通过cla()在每个地块之后和close()每个批次之后使用来解决该问题。

from matplotlib import pyplot as plt, patches
import os


def main():
    for i in range(21):
        print('Batch {}'.format(i))
        make_plots('figures')
    print('Done.')


def make_plots(path):
    fig, ax = plt.subplots()
    for i in range(21):
        x = range(3 * i)
        y = [n * n for n in x]
        ax.add_patch(patches.Rectangle(xy=(i, 1), width=i, height=10))
        plt.step(x, y, linewidth=2, where='mid')
        figname = 'fig_{}.png'.format(i)
        dest = os.path.join(path, figname)
        plt.savefig(dest)  # write image to file
        plt.cla()
    plt.close(fig)


main()

我测量了性能以查看是否值得在一批中重复使用该图,并且当我close()在每次绘图后都调用时,这个小示例程序从41s减至49s(慢20%)。

Here’s a bit more detail to expand on Hooked’s answer. When I first read that answer, I missed the instruction to call clf() instead of creating a new figure. clf() on its own doesn’t help if you then go and create another figure.

Here’s a trivial example that causes the warning:

from matplotlib import pyplot as plt, patches
import os


def main():
    path = 'figures'
    for i in range(21):
        _fig, ax = plt.subplots()
        x = range(3*i)
        y = [n*n for n in x]
        ax.add_patch(patches.Rectangle(xy=(i, 1), width=i, height=10))
        plt.step(x, y, linewidth=2, where='mid')
        figname = 'fig_{}.png'.format(i)
        dest = os.path.join(path, figname)
        plt.savefig(dest)  # write image to file
        plt.clf()
    print('Done.')

main()

To avoid the warning, I have to pull the call to subplots() outside the loop. In order to keep seeing the rectangles, I need to switch clf() to cla(). That clears the axis without removing the axis itself.

from matplotlib import pyplot as plt, patches
import os


def main():
    path = 'figures'
    _fig, ax = plt.subplots()
    for i in range(21):
        x = range(3*i)
        y = [n*n for n in x]
        ax.add_patch(patches.Rectangle(xy=(i, 1), width=i, height=10))
        plt.step(x, y, linewidth=2, where='mid')
        figname = 'fig_{}.png'.format(i)
        dest = os.path.join(path, figname)
        plt.savefig(dest)  # write image to file
        plt.cla()
    print('Done.')

main()

If you’re generating plots in batches, you might have to use both cla() and close(). I ran into a problem where a batch could have more than 20 plots without complaining, but it would complain after 20 batches. I fixed that by using cla() after each plot, and close() after each batch.

from matplotlib import pyplot as plt, patches
import os


def main():
    for i in range(21):
        print('Batch {}'.format(i))
        make_plots('figures')
    print('Done.')


def make_plots(path):
    fig, ax = plt.subplots()
    for i in range(21):
        x = range(3 * i)
        y = [n * n for n in x]
        ax.add_patch(patches.Rectangle(xy=(i, 1), width=i, height=10))
        plt.step(x, y, linewidth=2, where='mid')
        figname = 'fig_{}.png'.format(i)
        dest = os.path.join(path, figname)
        plt.savefig(dest)  # write image to file
        plt.cla()
    plt.close(fig)


main()

I measured the performance to see if it was worth reusing the figure within a batch, and this little sample program slowed from 41s to 49s (20% slower) when I just called close() after every plot.


回答 2

如果您打算有意识地在内存中保留许多绘图,但又不想被警告,则可以在生成图形之前更新选项。

import matplotlib.pyplot as plt
plt.rcParams.update({'figure.max_open_warning': 0})

这将防止发出警告,而无需更改有关内存管理方式的任何内容。

If you intend to knowingly keep many plots in memory, but don’t want to be warned about it, you can update your options prior to generating figures.

import matplotlib.pyplot as plt
plt.rcParams.update({'figure.max_open_warning': 0})

This will prevent the warning from being emitted without changing anything about the way memory is managed.


回答 3

以下代码段为我解决了这个问题:


class FigureWrapper(object):
    '''Frees underlying figure when it goes out of scope. 
    '''

    def __init__(self, figure):
        self._figure = figure

    def __del__(self):
        plt.close(self._figure)
        print("Figure removed")


# .....
    f, ax = plt.subplots(1, figsize=(20, 20))
    _wrapped_figure = FigureWrapper(f)

    ax.plot(...
    plt.savefig(...
# .....

_wrapped_figure超出范围时,运行时将在内部调用我们的__del__()方法plt.close()。即使在_wrapped_figure构造函数之后触发异常,也会发生这种情况。

The following snippet solved the issue for me:


class FigureWrapper(object):
    '''Frees underlying figure when it goes out of scope. 
    '''

    def __init__(self, figure):
        self._figure = figure

    def __del__(self):
        plt.close(self._figure)
        print("Figure removed")


# .....
    f, ax = plt.subplots(1, figsize=(20, 20))
    _wrapped_figure = FigureWrapper(f)

    ax.plot(...
    plt.savefig(...
# .....

When _wrapped_figure goes out of scope the runtime calls our __del__() method with plt.close() inside. It happens even if exception fires after _wrapped_figure constructor.


回答 4

如果您只想暂时取消警告,这也很有用:

    import matplotlib.pyplot as plt
       
    with plt.rc_context(rc={'figure.max_open_warning': 0}):
        lots_of_plots()

This is also useful if you only want to temporarily suppress the warning:

import matplotlib.pyplot as plt
       
with plt.rc_context(rc={'figure.max_open_warning': 0}):
    lots_of_plots()

如何告诉matplotlib我已经完成了情节?

问题:如何告诉matplotlib我已经完成了情节?

下面的代码绘制到两个PostScript(.ps)文件,但是第二个包含这两行。

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

plt.subplot(111)
x = [1,10]
y = [30, 1000]
plt.loglog(x, y, basex=10, basey=10, ls="-")
plt.savefig("first.ps")


plt.subplot(111)
x = [10,100]
y = [10, 10000]
plt.loglog(x, y, basex=10, basey=10, ls="-")
plt.savefig("second.ps")

如何告诉matplotlib重新开始第二个绘图?

The following code plots to two PostScript (.ps) files, but the second one contains both lines.

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

plt.subplot(111)
x = [1,10]
y = [30, 1000]
plt.loglog(x, y, basex=10, basey=10, ls="-")
plt.savefig("first.ps")


plt.subplot(111)
x = [10,100]
y = [10, 10000]
plt.loglog(x, y, basex=10, basey=10, ls="-")
plt.savefig("second.ps")

How can I tell matplotlib to start afresh for the second plot?


回答 0

figure例如,您可以用于创建新图,或者close在第一个图之后使用。

You can use figure to create a new plot, for example, or use close after the first plot.


回答 1

有一个清晰的图形命令,它应该为您完成:

plt.clf()

如果同一图中有多个子图

plt.cla()

清除当前轴。

There is a clear figure command, and it should do it for you:

plt.clf()

If you have multiple subplots in the same figure

plt.cla()

clears the current axes.


回答 2

如David Cournapeau所述,使用Figure()。

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

plt.figure()
x = [1,10]
y = [30, 1000]
plt.loglog(x, y, basex=10, basey=10, ls="-")
plt.savefig("first.ps")


plt.figure()
x = [10,100]
y = [10, 10000]
plt.loglog(x, y, basex=10, basey=10, ls="-")
plt.savefig("second.ps")

或子图(121)/子图(122)用于相同图,不同位置。

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

plt.subplot(121)
x = [1,10]
y = [30, 1000]
plt.loglog(x, y, basex=10, basey=10, ls="-")

plt.subplot(122)
x = [10,100]
y = [10, 10000]
plt.loglog(x, y, basex=10, basey=10, ls="-")
plt.savefig("second.ps")

As stated from David Cournapeau, use figure().

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

plt.figure()
x = [1,10]
y = [30, 1000]
plt.loglog(x, y, basex=10, basey=10, ls="-")
plt.savefig("first.ps")


plt.figure()
x = [10,100]
y = [10, 10000]
plt.loglog(x, y, basex=10, basey=10, ls="-")
plt.savefig("second.ps")

Or subplot(121) / subplot(122) for the same plot, different position.

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

plt.subplot(121)
x = [1,10]
y = [30, 1000]
plt.loglog(x, y, basex=10, basey=10, ls="-")

plt.subplot(122)
x = [10,100]
y = [10, 10000]
plt.loglog(x, y, basex=10, basey=10, ls="-")
plt.savefig("second.ps")

回答 3

只要plt.hold(False)在第一个plt.plot之前输入,就可以坚持原始代码。

Just enter plt.hold(False) before the first plt.plot, and you can stick to your original code.


回答 4

如果您以交互方式使用Matplotlib,例如在Web应用程序(例如ipython)中,则可能需要寻找

plt.show()

代替plt.close()plt.clf()

If you’re using Matplotlib interactively, for example in a web application, (e.g. ipython) you maybe looking for

plt.show()

instead of plt.close() or plt.clf().


回答 5

如果它们都不起作用,则检查此..说您是否沿各自的轴具有x和y数据数组。然后检查在哪个单元格(jupyter)中将x和y初始化为空。这是因为,也许您是将数据附加到x和y而不重新初始化它们。因此,情节也有旧数据。所以检查一下。

If none of them are working then check this.. say if you have x and y arrays of data along respective axis. Then check in which cell(jupyter) you have initialized x and y to empty. This is because , maybe you are appending data to x and y without re-initializing them. So plot has old data too. So check that..


使用Matplotlib在Python中绘制时间

问题:使用Matplotlib在Python中绘制时间

我有一个格式为(HH:MM:SS.mmmmmm)的时间戳数组和另一个浮点数数组,每个浮点数对应于timestamp数组中的一个值。

我可以使用Matplotlib在x轴上绘制时间,在y轴上绘制数字吗?

我试图这样做,但是不知何故它只接受浮点数数组。如何获取时间图?我必须以任何方式修改格式吗?

I have an array of timestamps in the format (HH:MM:SS.mmmmmm) and another array of floating point numbers, each corresponding to a value in the timestamp array.

Can I plot time on the x axis and the numbers on the y-axis using Matplotlib?

I was trying to, but somehow it was only accepting arrays of floats. How can I get it to plot the time? Do I have to modify the format in any way?


回答 0

您必须首先将时间戳转换为Python datetime对象(使用datetime.strptime)。然后使用date2num将日期转换为matplotlib格式。

使用plot_date以下方式绘制日期和值:

dates = matplotlib.dates.date2num(list_of_datetimes)
matplotlib.pyplot.plot_date(dates, values)

You must first convert your timestamps to Python datetime objects (use datetime.strptime). Then use date2num to convert the dates to matplotlib format.

Plot the dates and values using plot_date:

dates = matplotlib.dates.date2num(list_of_datetimes)
matplotlib.pyplot.plot_date(dates, values)

回答 1

您还可以使用pyplot.plot绘制时间戳,值对(从它们的字符串表示形式解析它们之后)。(使用matplotlib 1.2.0和1.3.1版进行了测试)

例:

import datetime
import random
import matplotlib.pyplot as plt

# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.plot(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()

plt.show()

结果图像:

线图


这与散点图相同:

import datetime
import random
import matplotlib.pyplot as plt

# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.scatter(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()

plt.show()

产生类似于此的图像:

散点图

You can also plot the timestamp, value pairs using pyplot.plot (after parsing them from their string representation). (Tested with matplotlib versions 1.2.0 and 1.3.1.)

Example:

import datetime
import random
import matplotlib.pyplot as plt

# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.plot(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()

plt.show()

Resulting image:

Line Plot


Here’s the same as a scatter plot:

import datetime
import random
import matplotlib.pyplot as plt

# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.scatter(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()

plt.show()

Produces an image similar to this:

Scatter Plot


回答 2

7年后,这段代码对我有所帮助。但是,我的时间仍然没有正确显示。

在此处输入图片说明

使用Matplotlib 2.0.0,我不得不从Paul H 编辑matplotlib中编辑x轴刻度标签的日期格式中添加以下代码。

import matplotlib.dates as mdates
myFmt = mdates.DateFormatter('%d')
ax.xaxis.set_major_formatter(myFmt)

我将格式更改为(%H:%M),并且时间显示正确。 在此处输入图片说明

非常感谢社区。

7 years later and this code has helped me. However, my times still were not showing up correctly.

enter image description here

Using Matplotlib 2.0.0 and I had to add the following bit of code from Editing the date formatting of x-axis tick labels in matplotlib by Paul H.

import matplotlib.dates as mdates
myFmt = mdates.DateFormatter('%d')
ax.xaxis.set_major_formatter(myFmt)

I changed the format to (%H:%M) and the time displayed correctly. enter image description here

All thanks to the community.


回答 3

我在使用matplotlib版本2.0.2时遇到了麻烦。从上面运行示例,我得到了一组居中的气泡集合。

气泡居中的堆栈图

我通过添加另一行“修复”了该问题:

plt.plot([],[])

整个代码段变为:

import datetime
import random
import matplotlib.pyplot as plt
import matplotlib.dates as mdates


# make up some data
x = [datetime.datetime.now() + datetime.timedelta(minutes=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.plot([],[])
plt.scatter(x,y)

# beautify the x-labels
plt.gcf().autofmt_xdate()
myFmt = mdates.DateFormatter('%H:%M')
plt.gca().xaxis.set_major_formatter(myFmt)

plt.show()
plt.close()

这将生成图像,其中气泡按需分布。

气泡随时间分布的图形

I had trouble with this using matplotlib version: 2.0.2. Running the example from above I got a centered stacked set of bubbles.

graph with centered stack of bubbles

I “fixed” the problem by adding another line:

plt.plot([],[])

The entire code snippet becomes:

import datetime
import random
import matplotlib.pyplot as plt
import matplotlib.dates as mdates


# make up some data
x = [datetime.datetime.now() + datetime.timedelta(minutes=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.plot([],[])
plt.scatter(x,y)

# beautify the x-labels
plt.gcf().autofmt_xdate()
myFmt = mdates.DateFormatter('%H:%M')
plt.gca().xaxis.set_major_formatter(myFmt)

plt.show()
plt.close()

This produces an image with the bubbles distributed as desired.

graph with bubbles distributed over time