plotnine - 在同一个图中有两个图并打印出来的任何解决方法
plotnine - Any work around to have two plots in the same figure and print it
我使用 python 中的 plotnine
绘制了两个图。我知道不支持绘制子图(here)。我想知道是否有一种方法可以解决并在一个图中创建子图。
我想用plotineplot.draw()
把它们做成一个图,然后用matplotlib读取它,或者先把它们保存为png,然后用matplotlib读取它们,然后把它们放在一起。但是,我对 matplotlib 不太熟悉,到目前为止的每一次尝试都是徒劳的。
样例 plotnine 图:
from plotnine import data
from plotnine import *
plot1 = (ggplot(data.mtcars, aes('wt', 'mpg', color='factor(gear)'))
+ geom_point()
+ stat_smooth(method='lm')
+ facet_wrap('~gear'))
任何帮助都会很有帮助。
最终我创建了一个解决方法,将绘图保存为图像,然后再次加载它们并组合它们。这不是最快或最有效的方法,但效果很好。
import plotnine as gg
import matplotlib.pyplot as plt
import matplotlib.image as img
import os
import numpy as np
def _check_plotnine_grid(plots_list, figsize):
if not type(plots_list) == list:
raise ValueError('Input plots_list is not a list')
if (not type(figsize) == tuple) or (not len(figsize) == 2):
raise ValueError('Input figsize should be a tuple of length 2')
def plotnine_grid(plots_list, row=None, col=1, height=None, width=None, dpi=500, ratio=None, pixels=10000,
figsize=(12, 8)):
"""
Create a grid of plotnine plots.
Function input
----------
plots_list : a list of plotnine.ggplots
row, col : numerics to indicate in how many rows and columns the plots should be ordered in the grid
defaults: row -> length of plots_list; col -> 1
height, width : the height and width of the individual subplots created by plotnine
can be automatically determined by a combination of dpi, ratio and pixels
dpi : the density of pixels in the image. Default: 500. Higher numbers could lead to crisper output,
depending on exact situation
ratio : the ratio of heigth to width in the output. Standard value is 1.5 x col/row.
Not used if height & width are given.
pixels : the total number of pixels used, default 10000. Not used if height & width are given.
figsize : tuple containing the size of the final output after making a grid, in pixels (default: (1200,800))
Function output
----------
A matplotlib figure that can be directly saved with output.savefig().
"""
_check_plotnine_grid(plots_list, figsize) # Check the input
# Assign values that have not been provided based on others. In the end, height and width should be provided.
if row is None:
row = len(plots_list)
if ratio is None:
ratio = 1.5 * col / row
if height is None and width is not None:
height = ratio * width
if height is not None and width is None:
width = height / ratio
if height is None and width is None:
area = pixels / dpi
width = np.sqrt(area/ratio)
height = ratio * width
# Do actual subplot creation and plot output.
i = 1
fig = plt.figure(figsize=figsize)
plt.autoscale(tight=True)
for image_sel in plots_list: # image_sel = plots_list[i]
image_sel.save('image' + str(i) + '.png', height=height, width=width, dpi=500, verbose=False)
fig.add_subplot(row, col, i)
plt.imshow(img.imread('image' + str(i) + '.png'), aspect='auto')
fig.tight_layout()
fig.get_axes()[i-1].axis('off')
i = i + 1
os.unlink('image' + str(i - 1) + '.png') # os.unlink is basically os.remove but in some cases quicker
fig.patch.set_visible(False)
return fig
最近,我正在开发 patchworklib,它是 matplotlib 的子图管理器,其灵感来自于 patchwork。它允许您仅使用 /
和 |
运算符快速安排多个 matplotlib 图,包括布局整齐的 plotnine 图。
这是示例代码,您也可以在 Google colab 上 运行:
import patchworklib as pw
from plotnine import *
from plotnine.data import *
g1 = (ggplot(mtcars) + geom_point(aes("mpg", "disp")))
g2 = (ggplot(mtcars) + geom_boxplot(aes("gear", "disp", group = "gear")))
g3 = (ggplot(mtcars, aes('wt', 'mpg', color='factor(gear)')) + geom_point() + stat_smooth(method='lm') + facet_wrap('~gear'))
g4 = (ggplot(data=diamonds) + geom_bar(mapping=aes(x="cut", fill="clarity"), position="dodge"))
g1 = pw.load_ggplot(g1, figsize=(2,3))
g2 = pw.load_ggplot(g2, figsize=(2,3))
g3 = pw.load_ggplot(g3, figsize=(3,3))
g4 = pw.load_ggplot(g4, figsize=(5,2))
g1234 = (g1|g2|g3)/g4
g1234.savefig()
我使用 python 中的 plotnine
绘制了两个图。我知道不支持绘制子图(here)。我想知道是否有一种方法可以解决并在一个图中创建子图。
我想用plotineplot.draw()
把它们做成一个图,然后用matplotlib读取它,或者先把它们保存为png,然后用matplotlib读取它们,然后把它们放在一起。但是,我对 matplotlib 不太熟悉,到目前为止的每一次尝试都是徒劳的。
样例 plotnine 图:
from plotnine import data
from plotnine import *
plot1 = (ggplot(data.mtcars, aes('wt', 'mpg', color='factor(gear)'))
+ geom_point()
+ stat_smooth(method='lm')
+ facet_wrap('~gear'))
任何帮助都会很有帮助。
最终我创建了一个解决方法,将绘图保存为图像,然后再次加载它们并组合它们。这不是最快或最有效的方法,但效果很好。
import plotnine as gg
import matplotlib.pyplot as plt
import matplotlib.image as img
import os
import numpy as np
def _check_plotnine_grid(plots_list, figsize):
if not type(plots_list) == list:
raise ValueError('Input plots_list is not a list')
if (not type(figsize) == tuple) or (not len(figsize) == 2):
raise ValueError('Input figsize should be a tuple of length 2')
def plotnine_grid(plots_list, row=None, col=1, height=None, width=None, dpi=500, ratio=None, pixels=10000,
figsize=(12, 8)):
"""
Create a grid of plotnine plots.
Function input
----------
plots_list : a list of plotnine.ggplots
row, col : numerics to indicate in how many rows and columns the plots should be ordered in the grid
defaults: row -> length of plots_list; col -> 1
height, width : the height and width of the individual subplots created by plotnine
can be automatically determined by a combination of dpi, ratio and pixels
dpi : the density of pixels in the image. Default: 500. Higher numbers could lead to crisper output,
depending on exact situation
ratio : the ratio of heigth to width in the output. Standard value is 1.5 x col/row.
Not used if height & width are given.
pixels : the total number of pixels used, default 10000. Not used if height & width are given.
figsize : tuple containing the size of the final output after making a grid, in pixels (default: (1200,800))
Function output
----------
A matplotlib figure that can be directly saved with output.savefig().
"""
_check_plotnine_grid(plots_list, figsize) # Check the input
# Assign values that have not been provided based on others. In the end, height and width should be provided.
if row is None:
row = len(plots_list)
if ratio is None:
ratio = 1.5 * col / row
if height is None and width is not None:
height = ratio * width
if height is not None and width is None:
width = height / ratio
if height is None and width is None:
area = pixels / dpi
width = np.sqrt(area/ratio)
height = ratio * width
# Do actual subplot creation and plot output.
i = 1
fig = plt.figure(figsize=figsize)
plt.autoscale(tight=True)
for image_sel in plots_list: # image_sel = plots_list[i]
image_sel.save('image' + str(i) + '.png', height=height, width=width, dpi=500, verbose=False)
fig.add_subplot(row, col, i)
plt.imshow(img.imread('image' + str(i) + '.png'), aspect='auto')
fig.tight_layout()
fig.get_axes()[i-1].axis('off')
i = i + 1
os.unlink('image' + str(i - 1) + '.png') # os.unlink is basically os.remove but in some cases quicker
fig.patch.set_visible(False)
return fig
最近,我正在开发 patchworklib,它是 matplotlib 的子图管理器,其灵感来自于 patchwork。它允许您仅使用 /
和 |
运算符快速安排多个 matplotlib 图,包括布局整齐的 plotnine 图。
这是示例代码,您也可以在 Google colab 上 运行:
import patchworklib as pw
from plotnine import *
from plotnine.data import *
g1 = (ggplot(mtcars) + geom_point(aes("mpg", "disp")))
g2 = (ggplot(mtcars) + geom_boxplot(aes("gear", "disp", group = "gear")))
g3 = (ggplot(mtcars, aes('wt', 'mpg', color='factor(gear)')) + geom_point() + stat_smooth(method='lm') + facet_wrap('~gear'))
g4 = (ggplot(data=diamonds) + geom_bar(mapping=aes(x="cut", fill="clarity"), position="dodge"))
g1 = pw.load_ggplot(g1, figsize=(2,3))
g2 = pw.load_ggplot(g2, figsize=(2,3))
g3 = pw.load_ggplot(g3, figsize=(3,3))
g4 = pw.load_ggplot(g4, figsize=(5,2))
g1234 = (g1|g2|g3)/g4
g1234.savefig()