标签归档:matplotlib

如何在IPython Notebook中打开交互式matplotlib窗口?

问题:如何在IPython Notebook中打开交互式matplotlib窗口?

我正在使用IPython,--pylab=inline有时想快速切换到交互式可缩放的matplotlib GUI来查看图(在终端Python控制台中绘制图时会弹出的图)。我该怎么办?最好不要离开或重新启动笔记本。

IPy笔记本中的内联绘图的问题在于它们的分辨率有限,我无法放大以查看一些较小的部分。使用从终端启动的maptlotlib GUI,我可以选择要放大的图形矩形,并相应地调整轴。我尝试过

from matplotlib import interactive
interactive(True)

interactive(False)

但这什么也没做。我在网上也找不到任何提示。

I am using IPython with --pylab=inline and would sometimes like to quickly switch to the interactive, zoomable matplotlib GUI for viewing plots (the one that pops up when you plot something in a terminal Python console). How could I do that? Preferably without leaving or restarting my notebook.

The problem with inline plots in IPy notebook is that they are of a limited resolution and I can’t zoom into them to see some smaller parts. With the maptlotlib GUI that starts from a terminal, I can select a rectangle of the graph that I want to zoom into and the axes adjust accordingly. I tried experimenting with

from matplotlib import interactive
interactive(True)

and

interactive(False)

but that didn’t do anything. I couldn’t find any hint online either.


回答 0

根据文档,您应该能够像这样来回切换:

In [2]: %matplotlib inline 
In [3]: plot(...)

In [4]: %matplotlib qt  # wx, gtk, osx, tk, empty uses default
In [5]: plot(...) 

然后会弹出一个常规绘图窗口(可能需要在笔记本计算机上重新启动)。

我希望这有帮助。

According to the documentation, you should be able to switch back and forth like this:

In [2]: %matplotlib inline 
In [3]: plot(...)

In [4]: %matplotlib qt  # wx, gtk, osx, tk, empty uses default
In [5]: plot(...) 

and that will pop up a regular plot window (a restart on the notebook may be necessary).

I hope this helps.


回答 1

如果您要做的只是从内联图切换到交互式图,然后再切换回去(以便可以平移/缩放),则最好使用%matplotlib magic。

#interactive plotting in separate window
%matplotlib qt 

然后返回html

#normal charts inside notebooks
%matplotlib inline 

%pylab magic会导入很多其他内容,甚至可能导致冲突。它执行“从pylab导入*”。

您还可以使用新的笔记本后端(在matplotlib 1.4中添加):

#interactive charts inside notebooks, matplotlib 1.4+
%matplotlib notebook 

如果您想在图表中增加交互性,可以查看mpld3bokeh。mpld3很棒,如果您没有大量数据点(例如<5k +),并且您想要使用普通的matplotlib语法,但与%matplotlib notebook相比,则具有更多的交互性。Bokeh可以处理大量数据,但是您需要学习它的语法,因为它是一个单独的库。

你也可以签出pivottablejs(pip installivottablejs)

from pivottablejs import pivot_ui
pivot_ui(df)

不管是多么酷的交互式数据探索,它都完全会破坏可重复性。它发生在我身上,所以一旦我感觉到数据,我就尝试只在早期就使用它,并切换到纯内联matplotlib / seaborn。

If all you want to do is to switch from inline plots to interactive and back (so that you can pan/zoom), it is better to use %matplotlib magic.

#interactive plotting in separate window
%matplotlib qt 

and back to html

#normal charts inside notebooks
%matplotlib inline 

%pylab magic imports a bunch of other things and may even result in a conflict. It does “from pylab import *”.

You also can use new notebook backend (added in matplotlib 1.4):

#interactive charts inside notebooks, matplotlib 1.4+
%matplotlib notebook 

If you want to have more interactivity in your charts, you can look at mpld3 and bokeh. mpld3 is great, if you don’t have ton’s of data points (e.g. <5k+) and you want to use normal matplotlib syntax, but more interactivity, compared to %matplotlib notebook . Bokeh can handle lots of data, but you need to learn it’s syntax as it is a separate library.

Also you can check out pivottablejs (pip install pivottablejs)

from pivottablejs import pivot_ui
pivot_ui(df)

However cool interactive data exploration is, it can totally mess with reproducibility. It has happened to me, so I try to use it only at the very early stage and switch to pure inline matplotlib/seaborn, once I got the feel for the data.


回答 2

从matplotlib 1.4.0开始,现在有一个用于笔记本的交互式后端

%matplotlib notebook

有一些版本的IPython尚未注册该别名,回退是:

%matplotlib nbagg

如果那不起作用,请更新您的IPython。

要玩这个游戏,请转到tmpnb.org

并粘贴

%matplotlib notebook

import pandas as pd
import numpy as np
import matplotlib

from matplotlib import pyplot as plt
import seaborn as sns

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

df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index,
                  columns=['A', 'B', 'C', 'D'])
df = df.cumsum()
df.plot(); plt.legend(loc='best')    

进入代码单元(或仅修改现有的python演示笔记本)

Starting with matplotlib 1.4.0 there is now an an interactive backend for use in the notebook

%matplotlib notebook

There are a few version of IPython which do not have that alias registered, the fall back is:

%matplotlib nbagg

If that does not work update you IPython.

To play with this, goto tmpnb.org

and paste

%matplotlib notebook

import pandas as pd
import numpy as np
import matplotlib

from matplotlib import pyplot as plt
import seaborn as sns

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

df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index,
                  columns=['A', 'B', 'C', 'D'])
df = df.cumsum()
df.plot(); plt.legend(loc='best')    

into a code cell (or just modify the existing python demo notebook)


回答 3

更好的解决方案可能是图表库。它使您能够使用出色的Highcharts javascript库制作精美的交互式绘图。Highcharts使用HTMLsvg标记,因此您的所有图表实际上都是矢量图像。

一些功能:

  • 您可以下载.png,.jpg和.svg格式的矢量图,因此永远不会遇到分辨率问题
  • 交互式图表(缩放,滑动,将鼠标悬停在点上,…)
  • 在IPython笔记本中可用
  • 使用异步绘图功能可同时探索数百个数据结构。

免责声明:我是图书馆的开发人员

A better solution for your problem might be the Charts library. It enables you to use the excellent Highcharts javascript library to make beautiful and interactive plots. Highcharts uses the HTML svg tag so all your charts are actually vector images.

Some features:

  • Vector plots which you can download in .png, .jpg and .svg formats so you will never run into resolution problems
  • Interactive charts (zoom, slide, hover over points, …)
  • Usable in an IPython notebook
  • Explore hundreds of data structures at the same time using the asynchronous plotting capabilities.

Disclaimer: I’m the developer of the library


回答 4

我在2011年5月28日从www.continuum.io/downloads的Anaconda的“ jupyter QTConsole”中使用ipython。

这是一个使用ipython magic在一个单独的窗口和一个内联绘图模式之间来回切换的示例。

>>> import matplotlib.pyplot as plt

# data to plot
>>> x1 = [x for x in range(20)]

# Show in separate window
>>> %matplotlib
>>> plt.plot(x1)
>>> plt.close() 

# Show in console window
>>> %matplotlib inline
>>> plt.plot(x1)
>>> plt.close() 

# Show in separate window
>>> %matplotlib
>>> plt.plot(x1)
>>> plt.close() 

# Show in console window
>>> %matplotlib inline
>>> plt.plot(x1)
>>> plt.close() 

# Note: the %matplotlib magic above causes:
#      plt.plot(...) 
# to implicitly include a:
#      plt.show()
# after the command.
#
# (Not sure how to turn off this behavior
# so that it matches behavior without using %matplotlib magic...)
# but its ok for interactive work...

I’m using ipython in “jupyter QTConsole” from Anaconda at www.continuum.io/downloads on 5/28/20117.

Here’s an example to flip back and forth between a separate window and an inline plot mode using ipython magic.

>>> import matplotlib.pyplot as plt

# data to plot
>>> x1 = [x for x in range(20)]

# Show in separate window
>>> %matplotlib
>>> plt.plot(x1)
>>> plt.close() 

# Show in console window
>>> %matplotlib inline
>>> plt.plot(x1)
>>> plt.close() 

# Show in separate window
>>> %matplotlib
>>> plt.plot(x1)
>>> plt.close() 

# Show in console window
>>> %matplotlib inline
>>> plt.plot(x1)
>>> plt.close() 

# Note: the %matplotlib magic above causes:
#      plt.plot(...) 
# to implicitly include a:
#      plt.show()
# after the command.
#
# (Not sure how to turn off this behavior
# so that it matches behavior without using %matplotlib magic...)
# but its ok for interactive work...

回答 5

重新启动内核并清除输出(如果不是从新笔记本开始),然后运行

%matplotlib tk

有关更多信息,请转到使用matplotlib进行绘图

Restart kernel and clear output (if not starting with new notebook), then run

%matplotlib tk

For more info go to Plotting with matplotlib


回答 6

您可以使用

%matplotlib qt

如果出现错误,ImportError: Failed to import any qt binding则将PyQt5安装为:pip install PyQt5它对我有用。

You can use

%matplotlib qt

If you got the error ImportError: Failed to import any qt binding then install PyQt5 as: pip install PyQt5 and it works for me.


Seaborn Barplot上的标签轴

问题:Seaborn Barplot上的标签轴

我正在尝试通过以下代码将自己的标签用于Seaborn barplot:

import pandas as pd
import seaborn as sns

fake = pd.DataFrame({'cat': ['red', 'green', 'blue'], 'val': [1, 2, 3]})
fig = sns.barplot(x = 'val', y = 'cat', 
                  data = fake, 
                  color = 'black')
fig.set_axis_labels('Colors', 'Values')

但是,我得到一个错误:

AttributeError: 'AxesSubplot' object has no attribute 'set_axis_labels'

是什么赋予了?

I’m trying to use my own labels for a Seaborn barplot with the following code:

import pandas as pd
import seaborn as sns

fake = pd.DataFrame({'cat': ['red', 'green', 'blue'], 'val': [1, 2, 3]})
fig = sns.barplot(x = 'val', y = 'cat', 
                  data = fake, 
                  color = 'black')
fig.set_axis_labels('Colors', 'Values')

However, I get an error that:

AttributeError: 'AxesSubplot' object has no attribute 'set_axis_labels'

What gives?


回答 0

Seaborn的条形图返回一个轴对象(不是图形)。这意味着您可以执行以下操作:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

fake = pd.DataFrame({'cat': ['red', 'green', 'blue'], 'val': [1, 2, 3]})
ax = sns.barplot(x = 'val', y = 'cat', 
              data = fake, 
              color = 'black')
ax.set(xlabel='common xlabel', ylabel='common ylabel')
plt.show()

Seaborn’s barplot returns an axis-object (not a figure). This means you can do the following:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

fake = pd.DataFrame({'cat': ['red', 'green', 'blue'], 'val': [1, 2, 3]})
ax = sns.barplot(x = 'val', y = 'cat', 
              data = fake, 
              color = 'black')
ax.set(xlabel='common xlabel', ylabel='common ylabel')
plt.show()

回答 1

使用和可以避免方法AttributeError带来的麻烦。set_axis_labels()matplotlib.pyplot.xlabelmatplotlib.pyplot.ylabel

matplotlib.pyplot.xlabel设置x轴标签,而matplotlib.pyplot.ylabel设置当前轴的y轴标签。

解决方案代码:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

fake = pd.DataFrame({'cat': ['red', 'green', 'blue'], 'val': [1, 2, 3]})
fig = sns.barplot(x = 'val', y = 'cat', data = fake, color = 'black')
plt.xlabel("Colors")
plt.ylabel("Values")
plt.title("Colors vs Values") # You can comment this line out if you don't need title
plt.show(fig)

输出图:

One can avoid the AttributeError brought about by set_axis_labels() method by using the matplotlib.pyplot.xlabel and matplotlib.pyplot.ylabel.

matplotlib.pyplot.xlabel sets the x-axis label while the matplotlib.pyplot.ylabel sets the y-axis label of the current axis.

Solution code:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

fake = pd.DataFrame({'cat': ['red', 'green', 'blue'], 'val': [1, 2, 3]})
fig = sns.barplot(x = 'val', y = 'cat', data = fake, color = 'black')
plt.xlabel("Colors")
plt.ylabel("Values")
plt.title("Colors vs Values") # You can comment this line out if you don't need title
plt.show(fig)

Output figure:


回答 2

您还可以通过添加title参数来设置图表标题,如下所示

ax.set(xlabel='common xlabel', ylabel='common ylabel', title='some title')

You can also set the title of your chart by adding the title parameter as follows

ax.set(xlabel='common xlabel', ylabel='common ylabel', title='some title')

“用户警告:Matplotlib当前正在使用agg,它是非GUI后端,因此无法显示该图。” 在Pycharm上用pyplot绘制图时

问题:“用户警告:Matplotlib当前正在使用agg,它是非GUI后端,因此无法显示该图。” 在Pycharm上用pyplot绘制图时

我正在尝试使用pyplot绘制一个简单的图形,例如:

import matplotlib.pyplot as plt
plt.plot([1,2,3],[5,7,4])
plt.show()

但该图未出现,并且我收到以下消息:

UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.

我在几个地方看到必须使用以下命令更改matplotlib的配置:

import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt

我这样做了,但是却收到一条错误消息,因为它找不到模块:

ModuleNotFoundError: No module named 'tkinter'

然后,我尝试使用安装“ tkinter” pip install tkinter(在虚拟环境中),但找不到它:

Collecting tkinter
  Could not find a version that satisfies the requirement tkinter (from versions: )
No matching distribution found for tkinter

我还应该提到,我正在使用虚拟环境在Pycharm Community Edition IDE上运行所有这些程序,并且我的操作系统是Linux / Ubuntu 18.04。

我想知道如何解决此问题才能显示图形。

I am trying to plot a simple graph using pyplot, e.g.:

import matplotlib.pyplot as plt
plt.plot([1,2,3],[5,7,4])
plt.show()

but the figure does not appear and I get the following message:

UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.

I saw in several places that one had to change the configuration of matplotlib using the following:

import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt

I did this, but then got an error message because it cannot find a module:

ModuleNotFoundError: No module named 'tkinter'

Then, I tried to install “tkinter” using pip install tkinter (inside the virtual environment), but it does not find it:

Collecting tkinter
  Could not find a version that satisfies the requirement tkinter (from versions: )
No matching distribution found for tkinter

I should also mention that I am running all this on Pycharm Community Edition IDE using a virtual environment, and that my operating system is Linux/Ubuntu 18.04.

I would like to know how I can solve this problem in order to be able to display the graph.


回答 0

我找到了解决问题的方法(借助于ImportanceOfBeingErnest的帮助)。

我要做的就是tkinter使用以下命令通过Linux bash终端安装:

sudo apt-get install python3-tk

而不是将其安装pip在Pycharm的虚拟环境中或直接安装在虚拟环境中。

I found a solution to my problem (thanks to the help of ImportanceOfBeingErnest).

All I had to do was to install tkinter through the Linux bash terminal using the following command:

sudo apt-get install python3-tk

instead of installing it with pip or directly in the virtual environment in Pycharm.


回答 1

就我而言,该错误消息表示我在无头控制台中工作。因此plt.show()无法正常工作。起作用的是plt.savefig

import matplotlib.pyplot as plt

plt.plot([1,2,3], [5,7,4])
plt.savefig("mygraph.png")

我在github仓库上找到了答案。

In my case, the error message was implying that I was working in a headless console. So plt.show() could not work. What worked was calling plt.savefig:

import matplotlib.pyplot as plt

plt.plot([1,2,3], [5,7,4])
plt.savefig("mygraph.png")

I found the answer on a github repository.


回答 2

如果您使用Arch Linux(分布类似ManjaroAntegros),只需键入:

sudo pacman -S tk

所有都将完美运行!

If you use Arch Linux (distributions like Manjaro or Antegros) simply type:

sudo pacman -S tk

And all will work perfectly!


回答 3

尝试一下,import tkinter因为pycharm已经为您安装了tkinter,所以我看了为Python安装tkinter

您可以尝试:

import tkinter
import matplotlib
matplotlib.use('TkAgg')
plt.plot([1,2,3],[5,7,4])
plt.show()

作为tkinter的安装方式

我已经尝试过,在计算机上运行似乎没有错误,它成功显示了该图。也许是因为pycharm将tkinter作为系统软件包,所以您不需要安装它。但是,如果您在内部找不到tkinter,则可以去Tkdocs看看安装tkinter的方法,正如它所提到的,tkinter是python的核心软件包。

Try import tkinter because pycharm already installed tkinter for you, I looked Install tkinter for Python

You can maybe try:

import tkinter
import matplotlib
matplotlib.use('TkAgg')
plt.plot([1,2,3],[5,7,4])
plt.show()

as a tkinter-installing way

I’ve tried your way, it seems no error to run at my computer, it successfully shows the figure. maybe because pycharm have tkinter as a system package, so u don’t need to install it. But if u can’t find tkinter inside, you can go to Tkdocs to see the way of installing tkinter, as it mentions, tkinter is a core package for python.


回答 4

我在PyCharm中也遇到了这个问题。此问题是因为您的计算机中没有tkinter模块。

要安装,请遵循以下步骤(选择合适的操作系统)

对于ubuntu用户

 sudo apt-get install python-tk

要么

 sudo apt-get install python3-tk

对于Centos用户

 sudo yum install python-tkinter

要么

 sudo yum install python3-tkinter

对于Windows,请使用pip安装tk

安装tkinter后,重新启动Pycharm并运行您的代码,它将起作用

I too had this issue in PyCharm. This issue is because you don’t have tkinter module in your machine.

To install follow the steps given below (select your appropriate os)

For ubuntu users

 sudo apt-get install python-tk

or

 sudo apt-get install python3-tk

For Centos users

 sudo yum install python-tkinter

or

 sudo yum install python3-tkinter

For Windows, use pip to install tk

After installing tkinter restart your Pycharm and run your code, it will work


回答 5

安装简单

pip3 install PyQt5==5.9.2

这个对我有用。

Simple install

pip3 install PyQt5==5.9.2

It works for me.


回答 6

您可以使用fromagg到Tkinter TKAggusing命令将后端使用的matplotlib更改为

matplotlib.use('TKAgg',warn=False, force=True)

You can change the matplotlib using backend using the from agg to Tkinter TKAgg using command

matplotlib.use('TKAgg',warn=False, force=True)

回答 7

Linux Mint 19.对我有帮助:

sudo apt install tk-dev

PS软件包安装后重新编译python解释器。

Linux Mint 19. Helped for me:

sudo apt install tk-dev

P.S. Recompile python interpreter after package install.


回答 8

以防万一这对任何人都有帮助。

Python版本:3.7.7平台:Ubuntu 18.04.4 LTS

这带有默认的python 3.6.9版本,但是我已经在上面安装了自己的3.7.7版本python(已从源代码安装了它)

即使当 help('module')列表中显示了tkinter,。

以下步骤对我有用:

  1. sudo apt-get install tk-dev.

重建python:1.导航到您的python文件夹并运行检查:

cd Python-3.7.7
sudo ./configure --enable-optimizations
  1. 使用make命令进行构建: sudo make -j 8 —这是8个处理器的数量,请使用nproc命令。
  2. 使用以下方式安装:

    sudo make altinstall
    

不要使用sudo make install,它将覆盖默认的3.6.9版本,以后可能会很混乱。

  1. 立即检查tkinter
    python3.7 -m tkinter
    

将弹出一个窗口框,您的Tkinter现在已准备就绪。

Just in case if this helps anybody.

Python version: 3.7.7 platform: Ubuntu 18.04.4 LTS

This came with default python version 3.6.9, however I had installed my own 3.7.7 version python on it (installed building it from source)

tkinter was not working even when the help('module') shows tkinter in the list.

The following steps worked for me:

  1. sudo apt-get install tk-dev.

rebuild the python: 1. Navigate to your python folder and run the checks:

cd Python-3.7.7
sudo ./configure --enable-optimizations
  1. Build using make command: sudo make -j 8 — here 8 are the number of processors, check yours using nproc command.
  2. Installing using:

    sudo make altinstall
    

Don’t use sudo make install, it will overwrite default 3.6.9 version, which might be messy later.

  1. Check tkinter now
    python3.7 -m tkinter
    

A windows box will pop up, your tkinter is ready now.


回答 9

在升级了很多软件包(Spyder3到4,Keras以及Tensorflow很多依赖)之后,我今天遇到了同样的问题!我不知道发生了什么事。但是继续使用Spyder3的(基于conda的)虚拟环境没有问题。尽管如上所示安装tkinter或更改了后端,via matplotlib.use('TkAgg)或者这篇有关如何更改后端的不错的帖子 可能很好地解决了问题,但我不认为这些是严格的解决方案。对我来说,卸载matplotlib并重新安装它是不可思议的,问题已解决。

pip uninstall matplotlib

…然后,安装

pip install matplotlib

综上所述,这可能是一个程序包管理问题,顺便说一句,在可行的情况下,我会同时使用condapip

After upgrading lots of packages (Spyder 3 to 4, Keras and Tensorflow and lots of their dependencies), I had the same problem today! I cannot figure out what happened; but the (conda-based) virtual environment that kept using Spyder 3 did not have the problem. Although installing tkinter or changing the backend, via matplotlib.use('TkAgg) as shown above, or this nice post on how to change the backend, might well resolve the problem, I don’t see these as rigid solutions. For me, uninstalling matplotlib and reinstalling it was magic and the problem was solved.

pip uninstall matplotlib

… then, install

pip install matplotlib

From all the above, this could be a package management problem, and BTW, I use both conda and pip, whenever feasible.


回答 10

当我在Spyder上遇到此错误时,我从逐行运行代码变为突出显示绘图代码块并立即运行所有代码。瞧,图像出现了。

When I ran into this error on Spyder, I changed from running my code line by line to highlighting my block of plotting code and running that all at once. Voila, the image appeared.


回答 11

内联添加了%matplotlib, 并且我的情节出现在Jupyter Notebook中。

I added %matplotlib inline and my plot showed up in Jupyter Notebook.


回答 12

@xicocaio的评论应突出显示。

从某种意义上说,tkinter是特定于python版本的,sudo apt-get install python3-tk它将专门为您的默认python版本安装tkinter。假设您在各种虚拟环境中具有不同的python版本,则必须为该虚拟环境中使用的所需python版本安装tkinter。例如,sudo apt-get install python3.7-tkNo module named ' tkinter'即使不为全局python版本安装它,这样做仍然会导致错误。

The comment by @xicocaio should be highlighted.

tkinter is python version-specific in the sense that sudo apt-get install python3-tk will install tkinter exclusively for your default version of python. Suppose you have different python versions within various virtual environments, you will have to install tkinter for the desired python version used in that virtual environment. For example, sudo apt-get install python3.7-tk. Not doing this will still lead to No module named ' tkinter' errors, even after installing it for the global python version.


Matplotlib:在其他图形元素后面绘制网格线

问题:Matplotlib:在其他图形元素后面绘制网格线

在Matplotlib中,我按如下所示制作虚线网格:

fig = pylab.figure()    
ax = fig.add_subplot(1,1,1)
ax.yaxis.grid(color='gray', linestyle='dashed')

但是,我不知道如何(甚至可能)在其他图形元素(如条形图)后面绘制网格线。更改添加网格的顺序与添加其他元素的顺序没有区别。

是否有可能使网格线出现在其他所有内容的后面?

In Matplotlib, I make dashed grid lines as follows:

fig = pylab.figure()    
ax = fig.add_subplot(1,1,1)
ax.yaxis.grid(color='gray', linestyle='dashed')

however, I can’t find out how (or even if it is possible) to make the grid lines be drawn behind other graph elements, such as bars. Changing the order of adding the grid versus adding other elements makes no difference.

Is it possible to make it so that the grid lines appear behind everything else?


回答 0

据此-http://matplotlib.1069221.n5.nabble.com/axis-elements-and-zorder-td5346.html-您可以使用Axis.set_axisbelow(True)

(我目前是第一次安装matplotlib,所以不知道这是否正确-我只是通过谷歌搜索“ matplotlib z顺序网格”找到它的-通常,“ z顺序”用于描述这种情况(z为轴“页面外”))

According to this – http://matplotlib.1069221.n5.nabble.com/axis-elements-and-zorder-td5346.html – you can use Axis.set_axisbelow(True)

(I am currently installing matplotlib for the first time, so have no idea if that’s correct – I just found it by googling “matplotlib z order grid” – “z order” is typically used to describe this kind of thing (z being the axis “out of the page”))


回答 1

对我来说,目前尚不清楚如何应用安德鲁·库克的答案,因此这是基于此的完整解决方案:

ax.set_axisbelow(True)
ax.yaxis.grid(color='gray', linestyle='dashed')

To me, it was unclear how to apply andrew cooke’s answer, so this is a complete solution based on that:

ax.set_axisbelow(True)
ax.yaxis.grid(color='gray', linestyle='dashed')

回答 2

如果要验证所有数字的设置,可以设置

plt.rc('axes', axisbelow=True)

要么

plt.rcParams['axes.axisbelow'] = True

它适用于Matplotlib> = 2.0。

If you want to validate the setting for all figures, you may set

plt.rc('axes', axisbelow=True)

or

plt.rcParams['axes.axisbelow'] = True

It works for Matplotlib>=2.0.


回答 3

我有同样的问题,以下工作:

[line.set_zorder(3) for line in ax.lines]
fig.show() # to update

提高3到一个更高的值,如果它不能正常工作。

I had the same problem and the following worked:

[line.set_zorder(3) for line in ax.lines]
fig.show() # to update

Increase 3to a higher value if it does not work.


如何在Python中创建具有不同线型的主要和次要网格线

问题:如何在Python中创建具有不同线型的主要和次要网格线

我目前正在使用matplotlib.pyplot图形来创建图形,并且希望使主要的网格线为实线和黑色,而次要的网格线为灰色或虚线。

在网格属性中,which=both/major/mine然后通过线型简单定义颜色和线型。有没有办法只指定次要线型?

我到目前为止合适的代码是

plt.plot(current, counts, 'rd', markersize=8)
plt.yscale('log')
plt.grid(b=True, which='both', color='0.65', linestyle='-')

I am currently using matplotlib.pyplot to create graphs and would like to have the major gridlines solid and black and the minor ones either greyed or dashed.

In the grid properties, which=both/major/mine, and then color and linestyle are defined simply by linestyle. Is there a way to specify minor linestyle only?

The appropriate code I have so far is

plt.plot(current, counts, 'rd', markersize=8)
plt.yscale('log')
plt.grid(b=True, which='both', color='0.65', linestyle='-')

回答 0

实际上,它和设置一样简单,major并且minor分别是:

In [9]: plot([23, 456, 676, 89, 906, 34, 2345])
Out[9]: [<matplotlib.lines.Line2D at 0x6112f90>]

In [10]: yscale('log')

In [11]: grid(b=True, which='major', color='b', linestyle='-')

In [12]: grid(b=True, which='minor', color='r', linestyle='--')

带有较小网格的陷阱是,您还必须打开较小的刻度线。在上面的代码中,这是通过完成的yscale('log'),但也可以通过完成plt.minorticks_on()

Actually, it is as simple as setting major and minor separately:

In [9]: plot([23, 456, 676, 89, 906, 34, 2345])
Out[9]: [<matplotlib.lines.Line2D at 0x6112f90>]

In [10]: yscale('log')

In [11]: grid(b=True, which='major', color='b', linestyle='-')

In [12]: grid(b=True, which='minor', color='r', linestyle='--')

The gotcha with minor grids is that you have to have minor tick marks turned on too. In the above code this is done by yscale('log'), but it can also be done with plt.minorticks_on().


回答 1

一种简单的DIY方法是自己制作网格:

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)

ax.plot([1,2,3], [2,3,4], 'ro')

for xmaj in ax.xaxis.get_majorticklocs():
  ax.axvline(x=xmaj, ls='-')
for xmin in ax.xaxis.get_minorticklocs():
  ax.axvline(x=xmin, ls='--')

for ymaj in ax.yaxis.get_majorticklocs():
  ax.axhline(y=ymaj, ls='-')
for ymin in ax.yaxis.get_minorticklocs():
  ax.axhline(y=ymin, ls='--')
plt.show()

A simple DIY way would be to make the grid yourself:

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)

ax.plot([1,2,3], [2,3,4], 'ro')

for xmaj in ax.xaxis.get_majorticklocs():
  ax.axvline(x=xmaj, ls='-')
for xmin in ax.xaxis.get_minorticklocs():
  ax.axvline(x=xmin, ls='--')

for ymaj in ax.yaxis.get_majorticklocs():
  ax.axhline(y=ymaj, ls='-')
for ymin in ax.yaxis.get_minorticklocs():
  ax.axhline(y=ymin, ls='--')
plt.show()

如何在matplotlib中创建密度图?

问题:如何在matplotlib中创建密度图?

在RI中,可以通过执行以下操作来创建所需的输出:

data = c(rep(1.5, 7), rep(2.5, 2), rep(3.5, 8),
         rep(4.5, 3), rep(5.5, 1), rep(6.5, 8))
plot(density(data, bw=0.5))

在python(带有matplotlib)中,我得到的最接近的是一个简单的直方图:

import matplotlib.pyplot as plt
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
plt.hist(data, bins=6)
plt.show()

我还尝试了normed = True参数,但除了尝试使高斯拟合直方图外什么也没有。

我的最新尝试是围绕scipy.statsgaussian_kde,以下是网上的示例,但到目前为止我一直没有成功。

In R I can create the desired output by doing:

data = c(rep(1.5, 7), rep(2.5, 2), rep(3.5, 8),
         rep(4.5, 3), rep(5.5, 1), rep(6.5, 8))
plot(density(data, bw=0.5))

In python (with matplotlib) the closest I got was with a simple histogram:

import matplotlib.pyplot as plt
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
plt.hist(data, bins=6)
plt.show()

I also tried the normed=True parameter but couldn’t get anything other than trying to fit a gaussian to the histogram.

My latest attempts were around scipy.stats and gaussian_kde, following examples on the web, but I’ve been unsuccessful so far.


回答 0

Sven展示了如何使用gaussian_kdeScipy中的类,但是您会注意到它与您使用R生成的类看起来不太一样。这是因为gaussian_kde尝试自动推断带宽。您可以使用带宽的方式改变功能发挥covariance_factor的的gaussian_kde类。首先,这是您无需更改该功能即可得到的结果:

但是,如果我使用以下代码:

import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import gaussian_kde
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
density = gaussian_kde(data)
xs = np.linspace(0,8,200)
density.covariance_factor = lambda : .25
density._compute_covariance()
plt.plot(xs,density(xs))
plt.show()

我懂了

这与您从R获得的收益非常接近。我做了什么?gaussian_kde使用可变函数covariance_factor来计算其带宽。在更改函数之前,covariance_factor针对此数据返回的值约为0.5。降低它会降低带宽。我必须_compute_covariance在更改该函数后调用,以便可以正确计算所有因素。它与R中的bw参数并不完全对应,但是希望它可以帮助您朝正确的方向前进。

Sven has shown how to use the class gaussian_kde from Scipy, but you will notice that it doesn’t look quite like what you generated with R. This is because gaussian_kde tries to infer the bandwidth automatically. You can play with the bandwidth in a way by changing the function covariance_factor of the gaussian_kde class. First, here is what you get without changing that function:

However, if I use the following code:

import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import gaussian_kde
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
density = gaussian_kde(data)
xs = np.linspace(0,8,200)
density.covariance_factor = lambda : .25
density._compute_covariance()
plt.plot(xs,density(xs))
plt.show()

I get

which is pretty close to what you are getting from R. What have I done? gaussian_kde uses a changable function, covariance_factor to calculate its bandwidth. Before changing the function, the value returned by covariance_factor for this data was about .5. Lowering this lowered the bandwidth. I had to call _compute_covariance after changing that function so that all of the factors would be calculated correctly. It isn’t an exact correspondence with the bw parameter from R, but hopefully it helps you get in the right direction.


回答 1

五年后,当我用Google搜索“如何使用python创建内核密度图”时,该线程仍显示在顶部!

如今,更简单的方法是使用seaborn,这是一个提供许多便捷的绘图功能和良好的样式管理的软件包。

import numpy as np
import seaborn as sns
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
sns.set_style('whitegrid')
sns.kdeplot(np.array(data), bw=0.5)

Five years later, when I Google “how to create a kernel density plot using python”, this thread still shows up at the top!

Today, a much easier way to do this is to use seaborn, a package that provides many convenient plotting functions and good style management.

import numpy as np
import seaborn as sns
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
sns.set_style('whitegrid')
sns.kdeplot(np.array(data), bw=0.5)


回答 2

选项1:

使用pandas数据框图(建立在之上matplotlib):

import pandas as pd
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
pd.DataFrame(data).plot(kind='density') # or pd.Series()

选项2:

使用distplotseaborn

import seaborn as sns
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
sns.distplot(data, hist=False)

Option 1:

Use pandas dataframe plot (built on top of matplotlib):

import pandas as pd
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
pd.DataFrame(data).plot(kind='density') # or pd.Series()

Option 2:

Use distplot of seaborn:

import seaborn as sns
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
sns.distplot(data, hist=False)


回答 3

也许尝试类似:

import matplotlib.pyplot as plt
import numpy
from scipy import stats
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
density = stats.kde.gaussian_kde(data)
x = numpy.arange(0., 8, .1)
plt.plot(x, density(x))
plt.show()

您可以轻松地用gaussian_kde()其他内核密度估计值代替。

Maybe try something like:

import matplotlib.pyplot as plt
import numpy
from scipy import stats
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
density = stats.kde.gaussian_kde(data)
x = numpy.arange(0., 8, .1)
plt.plot(x, density(x))
plt.show()

You can easily replace gaussian_kde() by a different kernel density estimate.


回答 4

也可以使用matplotlib创建密度图:函数plt.hist(data)返回密度图所需的y和x值(请参阅文档https://matplotlib.org/3.1.1/api/_as_gen/ matplotlib.pyplot.hist.html)。结果,以下代码通过使用matplotlib库创建了密度图:

import matplotlib.pyplot as plt
dat=[-1,2,1,4,-5,3,6,1,2,1,2,5,6,5,6,2,2,2]
a=plt.hist(dat,density=True)
plt.close()
plt.figure()
plt.plot(a[1][1:],a[0])      

该代码返回以下密度图

The density plot can also be created by using matplotlib: The function plt.hist(data) returns the y and x values necessary for the density plot (see the documentation https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.hist.html). Resultingly, the following code creates a density plot by using the matplotlib library:

import matplotlib.pyplot as plt
dat=[-1,2,1,4,-5,3,6,1,2,1,2,5,6,5,6,2,2,2]
a=plt.hist(dat,density=True)
plt.close()
plt.figure()
plt.plot(a[1][1:],a[0])      

This code returns the following density plot


保存交互式Matplotlib图形

问题:保存交互式Matplotlib图形

有没有一种方法可以保存Matplotlib图形,以便可以重新打开它并恢复典型的交互作用?(就像MATLAB中的.fig格式一样?)

我发现自己多次运行相同的脚本来生成这些交互式图形。或者我要向同事发送多个静态PNG文件,以显示绘图的不同方面。我宁愿发送图形对象,并让它们自己与之交互。

Is there a way to save a Matplotlib figure such that it can be re-opened and have typical interaction restored? (Like the .fig format in MATLAB?)

I find myself running the same scripts many times to generate these interactive figures. Or I’m sending my colleagues multiple static PNG files to show different aspects of a plot. I’d rather send the figure object and have them interact with it themselves.


回答 0

这将是一个很棒的功能,但是AFAIK并没有在Matplotlib中实现,并且由于存储数据的方式可能很难实现自己。

我建议(a)将数据处理与生成图形分开(以唯一的名称保存数据),然后编写图形生成脚本(加载已保存数据的指定文件)并根据需要进行编辑或(b )另存为PDF / SVG / PostScript格式,并在某些精美的图形编辑器(如Adobe Illustrator(或Inkscape))中进行编辑。

编辑后,2012年秋季:正如其他人在下面指出的(尽管在此提及,因为这是公认的答案),自1.2版以来,Matplotlib允许您腌制人物。如发行说明所述,这是一项实验性功能,不支持在一个matplotlib版本中保存图形并在另一个matplotlib版本中打开图形。从不受信任的来源恢复泡菜通常也是不安全的。

对于共享/以后的编辑图(需要首先进行大量数据处理,并且可能需要在几个月后进行调整,例如在科学出版物的同行评审中进行调整),我仍然建议(1)的工作流程具有数据处理脚本,该脚本在生成图之前将处理后的数据(放入绘图中)保存到文件中,并且(2)具有单独的绘图生成脚本(您可以根据需要进行调整)以重新创建绘图。通过这种方式,您可以为每个绘图快速运行脚本并重新生成脚本(并使用新数据快速复制绘图设置)。话虽如此,腌制一个人物可能会方便短期/互动/探索性数据分析。

This would be a great feature, but AFAIK it isn’t implemented in Matplotlib and likely would be difficult to implement yourself due to the way figures are stored.

I’d suggest either (a) separate processing the data from generating the figure (which saves data with a unique name) and write a figure generating script (loading a specified file of the saved data) and editing as you see fit or (b) save as PDF/SVG/PostScript format and edit in some fancy figure editor like Adobe Illustrator (or Inkscape).

EDIT post Fall 2012: As others pointed out below (though mentioning here as this is the accepted answer), Matplotlib since version 1.2 allowed you to pickle figures. As the release notes state, it is an experimental feature and does not support saving a figure in one matplotlib version and opening in another. It’s also generally unsecure to restore a pickle from an untrusted source.

For sharing/later editing plots (that require significant data processing first and may need to be tweaked months later say during peer review for a scientific publication), I still recommend the workflow of (1) have a data processing script that before generating a plot saves the processed data (that goes into your plot) into a file, and (2) have a separate plot generation script (that you adjust as necessary) to recreate the plot. This way for each plot you can quickly run a script and re-generate it (and quickly copy over your plot settings with new data). That said, pickling a figure could be convenient for short term/interactive/exploratory data analysis.


回答 1

我刚刚发现了如何做到这一点。@pelson提到的“实验泡菜支持”效果很好。

试试这个:

# Plot something
import matplotlib.pyplot as plt
fig,ax = plt.subplots()
ax.plot([1,2,3],[10,-10,30])

交互式调整后,将图形对象另存为二进制文件:

import pickle
pickle.dump(fig, open('FigureObject.fig.pickle', 'wb')) # This is for Python 3 - py2 may need `file` instead of `open`

稍后,打开图形并保存调整,并显示GUI交互性:

import pickle
figx = pickle.load(open('FigureObject.fig.pickle', 'rb'))

figx.show() # Show the figure, edit it, etc.!

您甚至可以从图中提取数据:

data = figx.axes[0].lines[0].get_data()

(它适用于线条,pcolor和imshow- pcolormesh可使用一些技巧来重建展平的数据。)

我从使用Pickle保存Matplotlib图形获得了出色的技巧。

I just found out how to do this. The “experimental pickle support” mentioned by @pelson works quite well.

Try this:

# Plot something
import matplotlib.pyplot as plt
fig,ax = plt.subplots()
ax.plot([1,2,3],[10,-10,30])

After your interactive tweaking, save the figure object as a binary file:

import pickle
pickle.dump(fig, open('FigureObject.fig.pickle', 'wb')) # This is for Python 3 - py2 may need `file` instead of `open`

Later, open the figure and the tweaks should be saved and GUI interactivity should be present:

import pickle
figx = pickle.load(open('FigureObject.fig.pickle', 'rb'))

figx.show() # Show the figure, edit it, etc.!

You can even extract the data from the plots:

data = figx.axes[0].lines[0].get_data()

(It works for lines, pcolor & imshow – pcolormesh works with some tricks to reconstruct the flattened data.)

I got the excellent tip from Saving Matplotlib Figures Using Pickle.


回答 2

从Matplotlib 1.2开始,我们现在具有实验性的pickle支持。试一试,看看它是否适合您的情况。如果您有任何问题,请通过Matplotlib邮件列表或通过在github.com/matplotlib/matplotlib上打开问题来告知我们

As of Matplotlib 1.2, we now have experimental pickle support. Give that a go and see if it works well for your case. If you have any issues, please let us know on the Matplotlib mailing list or by opening an issue on github.com/matplotlib/matplotlib.


回答 3

为什么不发送Python脚本呢?MATLAB的.fig文件要求收件人具有MATLAB才能显示它们,因此,这等效于发送需要Matplotlib显示的Python脚本。

或者(免责声明:我还没有尝试过),您可以尝试腌制该图:

import pickle
output = open('interactive figure.pickle', 'wb')
pickle.dump(gcf(), output)
output.close()

Why not just send the Python script? MATLAB’s .fig files require the recipient to have MATLAB to display them, so that’s about equivalent to sending a Python script that requires Matplotlib to display.

Alternatively (disclaimer: I haven’t tried this yet), you could try pickling the figure:

import pickle
output = open('interactive figure.pickle', 'wb')
pickle.dump(gcf(), output)
output.close()

回答 4

好问题。这是来自的文档文本pylab.save

pylab不再提供保存功能,尽管旧的pylab函数仍然可以作为matplotlib.mlab.save使用(您仍然可以在pylab中将其称为“ mlab.save”)。但是,对于纯文本文件,我们建议使用numpy.savetxt。为了保存numpy数组,我们建议使用numpy.save及其类似的numpy.load,它们可以在pylab中以np.save和np.load的形式提供。

Good question. Here is the doc text from pylab.save:

pylab no longer provides a save function, though the old pylab function is still available as matplotlib.mlab.save (you can still refer to it in pylab as “mlab.save”). However, for plain text files, we recommend numpy.savetxt. For saving numpy arrays, we recommend numpy.save, and its analog numpy.load, which are available in pylab as np.save and np.load.


回答 5

我想出了一种相对简单的方法(但还有些不常规)来保存我的matplotlib数字。它是这样的:

import libscript

import matplotlib.pyplot as plt
import numpy as np

t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2*np.pi*t)

#<plot>
plt.plot(t, s)
plt.xlabel('time (s)')
plt.ylabel('voltage (mV)')
plt.title('About as simple as it gets, folks')
plt.grid(True)
plt.show()
#</plot>

save_plot(fileName='plot_01.py',obj=sys.argv[0],sel='plot',ctx=libscript.get_ctx(ctx_global=globals(),ctx_local=locals()))

具有这样save_plot定义的功能(了解逻辑的简单版本):

def save_plot(fileName='',obj=None,sel='',ctx={}):
    """
    Save of matplolib plot to a stand alone python script containing all the data and configuration instructions to regenerate the interactive matplotlib figure.

    Parameters
    ----------
    fileName : [string] Path of the python script file to be created.
    obj : [object] Function or python object containing the lines of code to create and configure the plot to be saved.
    sel : [string] Name of the tag enclosing the lines of code to create and configure the plot to be saved.
    ctx : [dict] Dictionary containing the execution context. Values for variables not defined in the lines of code for the plot will be fetched from the context.

    Returns
    -------
    Return ``'done'`` once the plot has been saved to a python script file. This file contains all the input data and configuration to re-create the original interactive matplotlib figure.
    """
    import os
    import libscript

    N_indent=4

    src=libscript.get_src(obj=obj,sel=sel)
    src=libscript.prepend_ctx(src=src,ctx=ctx,debug=False)
    src='\n'.join([' '*N_indent+line for line in src.split('\n')])

    if(os.path.isfile(fileName)): os.remove(fileName)
    with open(fileName,'w') as f:
        f.write('import sys\n')
        f.write('sys.dont_write_bytecode=True\n')
        f.write('def main():\n')
        f.write(src+'\n')

        f.write('if(__name__=="__main__"):\n')
        f.write(' '*N_indent+'main()\n')

return 'done'

或定义如下功能save_plot(使用zip压缩以生成更浅的图形文件的更好版本):

def save_plot(fileName='',obj=None,sel='',ctx={}):

    import os
    import json
    import zlib
    import base64
    import libscript

    N_indent=4
    level=9#0 to 9, default: 6
    src=libscript.get_src(obj=obj,sel=sel)
    obj=libscript.load_obj(src=src,ctx=ctx,debug=False)
    bin=base64.b64encode(zlib.compress(json.dumps(obj),level))

    if(os.path.isfile(fileName)): os.remove(fileName)
    with open(fileName,'w') as f:
        f.write('import sys\n')
        f.write('sys.dont_write_bytecode=True\n')
        f.write('def main():\n')
        f.write(' '*N_indent+'import base64\n')
        f.write(' '*N_indent+'import zlib\n')
        f.write(' '*N_indent+'import json\n')
        f.write(' '*N_indent+'import libscript\n')
        f.write(' '*N_indent+'bin="'+str(bin)+'"\n')
        f.write(' '*N_indent+'obj=json.loads(zlib.decompress(base64.b64decode(bin)))\n')
        f.write(' '*N_indent+'libscript.exec_obj(obj=obj,tempfile=False)\n')

        f.write('if(__name__=="__main__"):\n')
        f.write(' '*N_indent+'main()\n')

return 'done'

这使用了libscript我自己的模块,该模块主要依赖于inspectast。如果有兴趣,我可以尝试在Github上分享它(首先需要进行一些清理,然后我才能开始使用Github)。

save_plot函数和libscript模块的思想是获取创建图形的python指令(使用module inspect),对其进行分析(使用module ast)以提取依赖于其的所有变量,函数和模块,从执行上下文中提取这些变量并对其进行序列化如python指令(变量的代码将类似于t=[0.0,2.0,0.01]…,模块的代码将类似于import matplotlib.pyplot as plt…)附加在该图指令之前。生成的python指令将另存为python脚本,其执行将重新构建原始的matplotlib图。

可以想象,这对于大多数(如果不是全部)matplotlib图形都适用。

I figured out a relatively simple way (yet slightly unconventional) to save my matplotlib figures. It works like this:

import libscript

import matplotlib.pyplot as plt
import numpy as np

t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2*np.pi*t)

#<plot>
plt.plot(t, s)
plt.xlabel('time (s)')
plt.ylabel('voltage (mV)')
plt.title('About as simple as it gets, folks')
plt.grid(True)
plt.show()
#</plot>

save_plot(fileName='plot_01.py',obj=sys.argv[0],sel='plot',ctx=libscript.get_ctx(ctx_global=globals(),ctx_local=locals()))

with function save_plot defined like this (simple version to understand the logic):

def save_plot(fileName='',obj=None,sel='',ctx={}):
    """
    Save of matplolib plot to a stand alone python script containing all the data and configuration instructions to regenerate the interactive matplotlib figure.

    Parameters
    ----------
    fileName : [string] Path of the python script file to be created.
    obj : [object] Function or python object containing the lines of code to create and configure the plot to be saved.
    sel : [string] Name of the tag enclosing the lines of code to create and configure the plot to be saved.
    ctx : [dict] Dictionary containing the execution context. Values for variables not defined in the lines of code for the plot will be fetched from the context.

    Returns
    -------
    Return ``'done'`` once the plot has been saved to a python script file. This file contains all the input data and configuration to re-create the original interactive matplotlib figure.
    """
    import os
    import libscript

    N_indent=4

    src=libscript.get_src(obj=obj,sel=sel)
    src=libscript.prepend_ctx(src=src,ctx=ctx,debug=False)
    src='\n'.join([' '*N_indent+line for line in src.split('\n')])

    if(os.path.isfile(fileName)): os.remove(fileName)
    with open(fileName,'w') as f:
        f.write('import sys\n')
        f.write('sys.dont_write_bytecode=True\n')
        f.write('def main():\n')
        f.write(src+'\n')

        f.write('if(__name__=="__main__"):\n')
        f.write(' '*N_indent+'main()\n')

return 'done'

or defining function save_plot like this (better version using zip compression to produce lighter figure files):

def save_plot(fileName='',obj=None,sel='',ctx={}):

    import os
    import json
    import zlib
    import base64
    import libscript

    N_indent=4
    level=9#0 to 9, default: 6
    src=libscript.get_src(obj=obj,sel=sel)
    obj=libscript.load_obj(src=src,ctx=ctx,debug=False)
    bin=base64.b64encode(zlib.compress(json.dumps(obj),level))

    if(os.path.isfile(fileName)): os.remove(fileName)
    with open(fileName,'w') as f:
        f.write('import sys\n')
        f.write('sys.dont_write_bytecode=True\n')
        f.write('def main():\n')
        f.write(' '*N_indent+'import base64\n')
        f.write(' '*N_indent+'import zlib\n')
        f.write(' '*N_indent+'import json\n')
        f.write(' '*N_indent+'import libscript\n')
        f.write(' '*N_indent+'bin="'+str(bin)+'"\n')
        f.write(' '*N_indent+'obj=json.loads(zlib.decompress(base64.b64decode(bin)))\n')
        f.write(' '*N_indent+'libscript.exec_obj(obj=obj,tempfile=False)\n')

        f.write('if(__name__=="__main__"):\n')
        f.write(' '*N_indent+'main()\n')

return 'done'

This makes use a module libscript of my own, which mostly relies on modules inspect and ast. I can try to share it on Github if interest is expressed (it would first require some cleanup and me to get started with Github).

The idea behind this save_plot function and libscript module is to fetch the python instructions that create the figure (using module inspect), analyze them (using module ast) to extract all variables, functions and modules import it relies on, extract these from the execution context and serialize them as python instructions (code for variables will be like t=[0.0,2.0,0.01] … and code for modules will be like import matplotlib.pyplot as plt …) prepended to the figure instructions. The resulting python instructions are saved as a python script whose execution will re-build the original matplotlib figure.

As you can imagine, this works well for most (if not all) matplotlib figures.


在matplotlib中的次要y轴上添加y轴标签

问题:在matplotlib中的次要y轴上添加y轴标签

我可以使用将y标签添加到左侧的y轴plt.ylabel,但是如何将其添加到辅助y轴呢?

table = sql.read_frame(query,connection)

table[0].plot(color=colors[0],ylim=(0,100))
table[1].plot(secondary_y=True,color=colors[1])
plt.ylabel('$')

I can add a y label to the left y-axis using plt.ylabel, but how can I add it to the secondary y-axis?

table = sql.read_frame(query,connection)

table[0].plot(color=colors[0],ylim=(0,100))
table[1].plot(secondary_y=True,color=colors[1])
plt.ylabel('$')

回答 0

最好的方法是axes直接与对象进行交互

import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 10, 0.1)
y1 = 0.05 * x**2
y2 = -1 *y1

fig, ax1 = plt.subplots()

ax2 = ax1.twinx()
ax1.plot(x, y1, 'g-')
ax2.plot(x, y2, 'b-')

ax1.set_xlabel('X data')
ax1.set_ylabel('Y1 data', color='g')
ax2.set_ylabel('Y2 data', color='b')

plt.show()

The best way is to interact with the axes object directly

import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 10, 0.1)
y1 = 0.05 * x**2
y2 = -1 *y1

fig, ax1 = plt.subplots()

ax2 = ax1.twinx()
ax1.plot(x, y1, 'g-')
ax2.plot(x, y2, 'b-')

ax1.set_xlabel('X data')
ax1.set_ylabel('Y1 data', color='g')
ax2.set_ylabel('Y2 data', color='b')

plt.show()


回答 1

有一个简单的解决方案,不会弄乱matplotlib:只是熊猫。

调整原始示例:

table = sql.read_frame(query,connection)

ax = table[0].plot(color=colors[0],ylim=(0,100))
ax2 = table[1].plot(secondary_y=True,color=colors[1], ax=ax)

ax.set_ylabel('Left axes label')
ax2.set_ylabel('Right axes label')

基本上,当secondary_y=True给定选项时(即使ax=ax也传递了),它会pandas.plot返回不同的轴,我们将使用这些轴来设置标签。

我知道很早以前就已经回答了,但是我认为这种方法值得。

There is a straightforward solution without messing with matplotlib: just pandas.

Tweaking the original example:

table = sql.read_frame(query,connection)

ax = table[0].plot(color=colors[0],ylim=(0,100))
ax2 = table[1].plot(secondary_y=True,color=colors[1], ax=ax)

ax.set_ylabel('Left axes label')
ax2.set_ylabel('Right axes label')

Basically, when the secondary_y=True option is given (eventhough ax=ax is passed too) pandas.plot returns a different axes which we use to set the labels.

I know this was answered long ago, but I think this approach worths it.


回答 2

我目前无法使用Python,但最不可思议的是:

fig = plt.figure()

axes1 = fig.add_subplot(111)
# set props for left y-axis here

axes2 = axes1.twinx()   # mirror them
axes2.set_ylabel(...)

I don’t have access to Python right now, but off the top of my head:

fig = plt.figure()

axes1 = fig.add_subplot(111)
# set props for left y-axis here

axes2 = axes1.twinx()   # mirror them
axes2.set_ylabel(...)

如何消除matplotlib中子图之间的间隙?

问题:如何消除matplotlib中子图之间的间隙?

下面的代码在子图之间产生间隙。如何消除子图之间的间隙并使图像紧密网格?

import matplotlib.pyplot as plt

for i in range(16):
    i = i + 1
    ax1 = plt.subplot(4, 4, i)
    plt.axis('on')
    ax1.set_xticklabels([])
    ax1.set_yticklabels([])
    ax1.set_aspect('equal')
    plt.subplots_adjust(wspace=None, hspace=None)
plt.show()

The code below produces gaps between the subplots. How do I remove the gaps between the subplots and make the image a tight grid?

import matplotlib.pyplot as plt

for i in range(16):
    i = i + 1
    ax1 = plt.subplot(4, 4, i)
    plt.axis('on')
    ax1.set_xticklabels([])
    ax1.set_yticklabels([])
    ax1.set_aspect('equal')
    plt.subplots_adjust(wspace=None, hspace=None)
plt.show()

回答 0

您可以使用gridspec来控制轴之间的间距。这里有更多信息

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

plt.figure(figsize = (4,4))
gs1 = gridspec.GridSpec(4, 4)
gs1.update(wspace=0.025, hspace=0.05) # set the spacing between axes. 

for i in range(16):
   # i = i + 1 # grid spec indexes from 0
    ax1 = plt.subplot(gs1[i])
    plt.axis('on')
    ax1.set_xticklabels([])
    ax1.set_yticklabels([])
    ax1.set_aspect('equal')

plt.show()

You can use gridspec to control the spacing between axes. There’s more information here.

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

plt.figure(figsize = (4,4))
gs1 = gridspec.GridSpec(4, 4)
gs1.update(wspace=0.025, hspace=0.05) # set the spacing between axes. 

for i in range(16):
   # i = i + 1 # grid spec indexes from 0
    ax1 = plt.subplot(gs1[i])
    plt.axis('on')
    ax1.set_xticklabels([])
    ax1.set_yticklabels([])
    ax1.set_aspect('equal')

plt.show()


回答 1

问题是使用aspect='equal',防止子图拉伸到任意纵横比并填满所有空白空间。

通常,这可以工作:

import matplotlib.pyplot as plt

ax = [plt.subplot(2,2,i+1) for i in range(4)]

for a in ax:
    a.set_xticklabels([])
    a.set_yticklabels([])

plt.subplots_adjust(wspace=0, hspace=0)

结果是这样的:

但是,使用aspect='equal',如以下代码所示:

import matplotlib.pyplot as plt

ax = [plt.subplot(2,2,i+1) for i in range(4)]

for a in ax:
    a.set_xticklabels([])
    a.set_yticklabels([])
    a.set_aspect('equal')

plt.subplots_adjust(wspace=0, hspace=0)

这是我们得到的:

第二种情况的区别在于,您已将x轴和y轴强制设置为具有相同数量的单位/像素。由于默认情况下轴从0变为1(即在绘制任何东西之前),因此使用aspect='equal'强制每个轴为正方形。由于该图不是正方形,因此pyplot会在水平轴之间增加额外的间距。

要解决此问题,可以将图形设置为具有正确的宽高比。我们将在这里使用面向对象的pyplot接口,我认为它通常是更好的:

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8,8)) # Notice the equal aspect ratio
ax = [fig.add_subplot(2,2,i+1) for i in range(4)]

for a in ax:
    a.set_xticklabels([])
    a.set_yticklabels([])
    a.set_aspect('equal')

fig.subplots_adjust(wspace=0, hspace=0)

结果如下:

The problem is the use of aspect='equal', which prevents the subplots from stretching to an arbitrary aspect ratio and filling up all the empty space.

Normally, this would work:

import matplotlib.pyplot as plt

ax = [plt.subplot(2,2,i+1) for i in range(4)]

for a in ax:
    a.set_xticklabels([])
    a.set_yticklabels([])

plt.subplots_adjust(wspace=0, hspace=0)

The result is this:

However, with aspect='equal', as in the following code:

import matplotlib.pyplot as plt

ax = [plt.subplot(2,2,i+1) for i in range(4)]

for a in ax:
    a.set_xticklabels([])
    a.set_yticklabels([])
    a.set_aspect('equal')

plt.subplots_adjust(wspace=0, hspace=0)

This is what we get:

The difference in this second case is that you’ve forced the x- and y-axes to have the same number of units/pixel. Since the axes go from 0 to 1 by default (i.e., before you plot anything), using aspect='equal' forces each axis to be a square. Since the figure is not a square, pyplot adds in extra spacing between the axes horizontally.

To get around this problem, you can set your figure to have the correct aspect ratio. We’re going to use the object-oriented pyplot interface here, which I consider to be superior in general:

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8,8)) # Notice the equal aspect ratio
ax = [fig.add_subplot(2,2,i+1) for i in range(4)]

for a in ax:
    a.set_xticklabels([])
    a.set_yticklabels([])
    a.set_aspect('equal')

fig.subplots_adjust(wspace=0, hspace=0)

Here’s the result:


回答 2

在不完全采用gridspec的情况下,还可以通过将wspacehspace设置为零来使用以下方法消除差距:

import matplotlib.pyplot as plt

plt.clf()
f, axarr = plt.subplots(4, 4, gridspec_kw = {'wspace':0, 'hspace':0})

for i, ax in enumerate(f.axes):
    ax.grid('on', linestyle='--')
    ax.set_xticklabels([])
    ax.set_yticklabels([])

plt.show()
plt.close()

导致:

Without resorting gridspec entirely, the following might also be used to remove the gaps by setting wspace and hspace to zero:

import matplotlib.pyplot as plt

plt.clf()
f, axarr = plt.subplots(4, 4, gridspec_kw = {'wspace':0, 'hspace':0})

for i, ax in enumerate(f.axes):
    ax.grid('on', linestyle='--')
    ax.set_xticklabels([])
    ax.set_yticklabels([])

plt.show()
plt.close()

Resulting in:


回答 3

你试过了plt.tight_layout()吗?

plt.tight_layout() 没有它:

或者:类似这样的东西(使用add_axes

left=[0.1,0.3,0.5,0.7]
width=[0.2,0.2, 0.2, 0.2]
rectLS=[]
for x in left:
   for y in left:
       rectLS.append([x, y, 0.2, 0.2])
axLS=[]
fig=plt.figure()
axLS.append(fig.add_axes(rectLS[0]))
for i in [1,2,3]:
     axLS.append(fig.add_axes(rectLS[i],sharey=axLS[-1]))    
axLS.append(fig.add_axes(rectLS[4]))
for i in [1,2,3]:
     axLS.append(fig.add_axes(rectLS[i+4],sharex=axLS[i],sharey=axLS[-1]))
axLS.append(fig.add_axes(rectLS[8]))
for i in [5,6,7]:
     axLS.append(fig.add_axes(rectLS[i+4],sharex=axLS[i],sharey=axLS[-1]))     
axLS.append(fig.add_axes(rectLS[12]))
for i in [9,10,11]:
     axLS.append(fig.add_axes(rectLS[i+4],sharex=axLS[i],sharey=axLS[-1]))

如果您不需要共享轴,则只需 axLS=map(fig.add_axes, rectLS)

Have you tried plt.tight_layout()?

with plt.tight_layout() without it:

Or: something like this (use add_axes)

left=[0.1,0.3,0.5,0.7]
width=[0.2,0.2, 0.2, 0.2]
rectLS=[]
for x in left:
   for y in left:
       rectLS.append([x, y, 0.2, 0.2])
axLS=[]
fig=plt.figure()
axLS.append(fig.add_axes(rectLS[0]))
for i in [1,2,3]:
     axLS.append(fig.add_axes(rectLS[i],sharey=axLS[-1]))    
axLS.append(fig.add_axes(rectLS[4]))
for i in [1,2,3]:
     axLS.append(fig.add_axes(rectLS[i+4],sharex=axLS[i],sharey=axLS[-1]))
axLS.append(fig.add_axes(rectLS[8]))
for i in [5,6,7]:
     axLS.append(fig.add_axes(rectLS[i+4],sharex=axLS[i],sharey=axLS[-1]))     
axLS.append(fig.add_axes(rectLS[12]))
for i in [9,10,11]:
     axLS.append(fig.add_axes(rectLS[i+4],sharex=axLS[i],sharey=axLS[-1]))

If you don’t need to share axes, then simply axLS=map(fig.add_axes, rectLS)


回答 4

对于最新的matplotlib版本,您可能需要尝试Constrained Layoutplt.subplot()但是,这不起作用,因此您需要使用plt.subplots()

fig, axs = plt.subplots(4, 4, constrained_layout=True)

With recent matplotlib versions you might want to try Constrained Layout. This does not work with plt.subplot() however, so you need to use plt.subplots() instead:

fig, axs = plt.subplots(4, 4, constrained_layout=True)

python图正态分布

问题:python图正态分布

给定一个均值和方差,是否有一个简单的函数调用可以绘制正态分布?

Given a mean and a variance is there a simple function call which will plot a normal distribution?


回答 0

import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as stats
import math

mu = 0
variance = 1
sigma = math.sqrt(variance)
x = np.linspace(mu - 3*sigma, mu + 3*sigma, 100)
plt.plot(x, stats.norm.pdf(x, mu, sigma))
plt.show()

import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as stats
import math

mu = 0
variance = 1
sigma = math.sqrt(variance)
x = np.linspace(mu - 3*sigma, mu + 3*sigma, 100)
plt.plot(x, stats.norm.pdf(x, mu, sigma))
plt.show()


回答 1

我认为没有一个函数可以在一个调用中完成所有这些操作。但是,您可以在中找到高斯概率密度函数scipy.stats

因此,我想出的最简单方法是:

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

# Plot between -10 and 10 with .001 steps.
x_axis = np.arange(-10, 10, 0.001)
# Mean = 0, SD = 2.
plt.plot(x_axis, norm.pdf(x_axis,0,2))
plt.show()

资料来源:

I don’t think there is a function that does all that in a single call. However you can find the Gaussian probability density function in scipy.stats.

So the simplest way I could come up with is:

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

# Plot between -10 and 10 with .001 steps.
x_axis = np.arange(-10, 10, 0.001)
# Mean = 0, SD = 2.
plt.plot(x_axis, norm.pdf(x_axis,0,2))
plt.show()

Sources:


回答 2

使用seaborn代替我正在使用均值= 5 std = 3的1000值的seaborn的distplot

value = np.random.normal(loc=5,scale=3,size=1000)
sns.distplot(value)

您将获得正态分布曲线

Use seaborn instead i am using distplot of seaborn with mean=5 std=3 of 1000 values

value = np.random.normal(loc=5,scale=3,size=1000)
sns.distplot(value)

You will get a normal distribution curve


回答 3

Unutbu的答案是正确的。但是因为我们的平均值可以大于或小于零,所以我还是想更改一下:

x = np.linspace(-3 * sigma, 3 * sigma, 100)

对此:

x = np.linspace(-3 * sigma + mean, 3 * sigma + mean, 100)

Unutbu answer is correct. But because our mean can be more or less than zero I would still like to change this :

x = np.linspace(-3 * sigma, 3 * sigma, 100)

to this :

x = np.linspace(-3 * sigma + mean, 3 * sigma + mean, 100)

回答 4

如果您喜欢使用逐步方法,可以考虑以下解决方案

import numpy as np
import matplotlib.pyplot as plt

mean = 0; std = 1; variance = np.square(std)
x = np.arange(-5,5,.01)
f = np.exp(-np.square(x-mean)/2*variance)/(np.sqrt(2*np.pi*variance))

plt.plot(x,f)
plt.ylabel('gaussian distribution')
plt.show()

If you prefer to use a step by step approach you could consider a solution like follows

import numpy as np
import matplotlib.pyplot as plt

mean = 0; std = 1; variance = np.square(std)
x = np.arange(-5,5,.01)
f = np.exp(-np.square(x-mean)/2*variance)/(np.sqrt(2*np.pi*variance))

plt.plot(x,f)
plt.ylabel('gaussian distribution')
plt.show()

回答 5

我刚刚回到这个问题,我不得不安装scipy,因为MatplotlibDeprecationWarning: scipy.stats.norm.pdf在尝试上述示例时,matplotlib.mlab给了我错误消息。现在的示例是:

%matplotlib inline
import math
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats


mu = 0
variance = 1
sigma = math.sqrt(variance)
x = np.linspace(mu - 3*sigma, mu + 3*sigma, 100)
plt.plot(x, scipy.stats.norm.pdf(x, mu, sigma))

plt.show()

I have just come back to this and I had to install scipy as matplotlib.mlab gave me the error message MatplotlibDeprecationWarning: scipy.stats.norm.pdf when trying example above. So the sample is now:

%matplotlib inline
import math
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats


mu = 0
variance = 1
sigma = math.sqrt(variance)
x = np.linspace(mu - 3*sigma, mu + 3*sigma, 100)
plt.plot(x, scipy.stats.norm.pdf(x, mu, sigma))

plt.show()

回答 6

我相信设置高度很重要,因此创建了以下功能:

def my_gauss(x, sigma=1, h=1, mid=0):
    from math import exp, pow
    variance = pow(sdev, 2)
    return h * exp(-pow(x-mid, 2)/(2*variance))

其中sigma,标准偏差h为,高度mid为平均值。

这是使用不同高度和偏差的结果:

I believe that is important to set the height, so created this function:

def my_gauss(x, sigma=1, h=1, mid=0):
    from math import exp, pow
    variance = pow(sdev, 2)
    return h * exp(-pow(x-mid, 2)/(2*variance))

Where sigma is the standard deviation, h is the height and mid is the mean.

Here is the result using different heights and deviations:


回答 7

您可以轻松获得CDF。所以通过cdf pdf

    import numpy as np
    import matplotlib.pyplot as plt
    import scipy.interpolate
    import scipy.stats

    def setGridLine(ax):
        #http://jonathansoma.com/lede/data-studio/matplotlib/adding-grid-lines-to-a-matplotlib-chart/
        ax.set_axisbelow(True)
        ax.minorticks_on()
        ax.grid(which='major', linestyle='-', linewidth=0.5, color='grey')
        ax.grid(which='minor', linestyle=':', linewidth=0.5, color='#a6a6a6')
        ax.tick_params(which='both', # Options for both major and minor ticks
                        top=False, # turn off top ticks
                        left=False, # turn off left ticks
                        right=False,  # turn off right ticks
                        bottom=False) # turn off bottom ticks

    data1 = np.random.normal(0,1,1000000)
    x=np.sort(data1)
    y=np.arange(x.shape[0])/(x.shape[0]+1)

    f2 = scipy.interpolate.interp1d(x, y,kind='linear')
    x2 = np.linspace(x[0],x[-1],1001)
    y2 = f2(x2)

    y2b = np.diff(y2)/np.diff(x2)
    x2b=(x2[1:]+x2[:-1])/2.

    f3 = scipy.interpolate.interp1d(x, y,kind='cubic')
    x3 = np.linspace(x[0],x[-1],1001)
    y3 = f3(x3)

    y3b = np.diff(y3)/np.diff(x3)
    x3b=(x3[1:]+x3[:-1])/2.

    bins=np.arange(-4,4,0.1)
    bins_centers=0.5*(bins[1:]+bins[:-1])
    cdf = scipy.stats.norm.cdf(bins_centers)
    pdf = scipy.stats.norm.pdf(bins_centers)

    plt.rcParams["font.size"] = 18
    fig, ax = plt.subplots(3,1,figsize=(10,16))
    ax[0].set_title("cdf")
    ax[0].plot(x,y,label="data")
    ax[0].plot(x2,y2,label="linear")
    ax[0].plot(x3,y3,label="cubic")
    ax[0].plot(bins_centers,cdf,label="ans")

    ax[1].set_title("pdf:linear")
    ax[1].plot(x2b,y2b,label="linear")
    ax[1].plot(bins_centers,pdf,label="ans")

    ax[2].set_title("pdf:cubic")
    ax[2].plot(x3b,y3b,label="cubic")
    ax[2].plot(bins_centers,pdf,label="ans")

    for idx in range(3):
        ax[idx].legend()
        setGridLine(ax[idx])

    plt.show()
    plt.clf()
    plt.close()

you can get cdf easily. so pdf via cdf

    import numpy as np
    import matplotlib.pyplot as plt
    import scipy.interpolate
    import scipy.stats

    def setGridLine(ax):
        #http://jonathansoma.com/lede/data-studio/matplotlib/adding-grid-lines-to-a-matplotlib-chart/
        ax.set_axisbelow(True)
        ax.minorticks_on()
        ax.grid(which='major', linestyle='-', linewidth=0.5, color='grey')
        ax.grid(which='minor', linestyle=':', linewidth=0.5, color='#a6a6a6')
        ax.tick_params(which='both', # Options for both major and minor ticks
                        top=False, # turn off top ticks
                        left=False, # turn off left ticks
                        right=False,  # turn off right ticks
                        bottom=False) # turn off bottom ticks

    data1 = np.random.normal(0,1,1000000)
    x=np.sort(data1)
    y=np.arange(x.shape[0])/(x.shape[0]+1)

    f2 = scipy.interpolate.interp1d(x, y,kind='linear')
    x2 = np.linspace(x[0],x[-1],1001)
    y2 = f2(x2)

    y2b = np.diff(y2)/np.diff(x2)
    x2b=(x2[1:]+x2[:-1])/2.

    f3 = scipy.interpolate.interp1d(x, y,kind='cubic')
    x3 = np.linspace(x[0],x[-1],1001)
    y3 = f3(x3)

    y3b = np.diff(y3)/np.diff(x3)
    x3b=(x3[1:]+x3[:-1])/2.

    bins=np.arange(-4,4,0.1)
    bins_centers=0.5*(bins[1:]+bins[:-1])
    cdf = scipy.stats.norm.cdf(bins_centers)
    pdf = scipy.stats.norm.pdf(bins_centers)

    plt.rcParams["font.size"] = 18
    fig, ax = plt.subplots(3,1,figsize=(10,16))
    ax[0].set_title("cdf")
    ax[0].plot(x,y,label="data")
    ax[0].plot(x2,y2,label="linear")
    ax[0].plot(x3,y3,label="cubic")
    ax[0].plot(bins_centers,cdf,label="ans")

    ax[1].set_title("pdf:linear")
    ax[1].plot(x2b,y2b,label="linear")
    ax[1].plot(bins_centers,pdf,label="ans")

    ax[2].set_title("pdf:cubic")
    ax[2].plot(x3b,y3b,label="cubic")
    ax[2].plot(bins_centers,pdf,label="ans")

    for idx in range(3):
        ax[idx].legend()
        setGridLine(ax[idx])

    plt.show()
    plt.clf()
    plt.close()