TL; DR : С самого начала position = "dodge"
(или position = position_dodge(
) не делали то, что, как вы думали, делали.
position_dodge
является одной из функций настройки положения, доступных в пакете ggplot2. Если есть несколько элементов , принадлежащих к разным группам , занимающих одно и то же место, position_identity
вообще ничего не сделает, position_dodge
разместит элементы рядом друг с другом горизонтально, position_stack
поместил бы их друг на друга вертикально, position_fill
разместил бы их друг на друге вертикально & amp; растягиваться пропорционально, чтобы соответствовать всей площади участка и т. д.
Ниже приведено краткое описание поведения различных функций регулировки положения из шпаргалки RStudio ggplot2 :
[1154 ] Обратите внимание, что элементы, которые будут уклонены / и т. Д., Должны принадлежать к разным группам. Если group =
указано явно на графике, это будет использоваться в качестве переменной группировки для определения, какие элементы должны быть уклонены / и т. Д. Друг от друга. Если в aes()
нет явного группового отображения, но есть одно или несколько из color =
/ fill =
/ linetype =
/ и т. Д., Будет использовано взаимодействие всех дискретных переменных. Из ?aes_group_order
:
По умолчанию группа настроена на взаимодействие всех дискретных переменных в графике. Это часто правильно разделяет данные, но если это не так, или когда на графике не используется дискретная переменная, вам нужно будет явно определить структуру группировки, сопоставив группу с переменной, имеющей различное значение для каждой группы. [ 1155] blockquote>
Построение графика по графику
Начнем с вашего исходного графика. Поскольку в эстетических отображениях сюжета не было какой-либо группирующей переменной,
position = "dodge"
абсолютно ничего не сделал .Мы можем заменить это на
position = "identity"
для обоих слоев geom (на самом деле,position = "identity"
является позицией по умолчанию дляgeom_errorbar
, так что нет необходимости прописывать ее), и результирующий график будет одинаковым. [+1157]Увеличение прозрачности делает очевидным, что два бара занимают одно и то же место, один «позади» другого.
Думаю, этот оригинальный сюжет не , что вы на самом деле намеревались? На самом деле существует очень мало сценариев, в которых было бы целесообразно, чтобы один бар был позади другого, как этот ...
ggplot(data = df, aes(x=group1, y = mean))+ geom_col(position = 'dodge') + geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd), position = 'dodge') + ggtitle("original plot") ggplot(data = df, aes(x=group1, y = mean))+ geom_col(position = "identity") + geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd)) + ggtitle("remove position dodge") ggplot(data = df, aes(x=group1, y = mean))+ geom_col(position = "identity", alpha = 0.5) + geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd)) + ggtitle("increase transparency")
Я пропущу второй сюжет, так как добавление
width = 0.2
не изменило ничего фундаментального.На третьем графике мы наконец-то применили
position = "dodge"
, потому что теперь есть групповая переменная. Бары и усилители Панели ошибок перемещаются соответственно в зависимости от их ширины. Это ожидаемое поведение , если вместоposition = position_dodge(width =
используется, ...) position = "dodge"
, где уклоненное расстояние по умолчанию следует ширине слоя геома, если только оно не переопределено конкретным значением вposition_dodge(width = ...)
.Если бы слой
geom_errorbar
сохранял свою ширину по умолчанию (которая равна ширине по умолчанию дляgeom_col
), элементы обоих слоев были бы уклонены на одинаковую величину.ggplot(data = df, aes(x=group1, y = mean, fill = group2))+ geom_col(position = 'dodge') + geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd), width = 0.2, position = 'dodge') + ggtitle("third plot") ggplot(data = df, aes(x=group1, y = mean, fill = group2))+ geom_col(position = 'dodge') + geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd), position = 'dodge') + ggtitle("with default width")
Примечание : Мы знаем
geom_errorbar
и amp;geom_col
имеют одинаковую ширину по умолчанию, потому что они настраивают свои данные одинаковым образом. Следующая строка кода может быть найдена вGeomErrorbar$setup_data
/GeomCol$setup_data
:data$width <- data$width %||% params$width %||% (resolution(data$x, FALSE) * 0.9) # i.e. if width is specified as one of the aesthetic mappings, use that; # else if width is specified in the geom layer's parameters, use that; # else, use 90% of the dataset's x-axis variable's resolution. <- default value of 0.9
В заключение, если у вас разные эстетические группы, указание ширины в
position_dodge
определяет расстояние, которое перемещает каждый элемент, при этом указав ширину в каждом слое geom определяет каждый элемент ... ну, ширина. Пока разные слои геомов уклоняются от одинакового количества, они будут выровнены друг с другом.Ниже приведен случайный пример для иллюстрации, в котором используются разные значения ширины для каждого слоя (0,5 для
geom_col
, 0,9 дляgeom_errorbar
), но одинаковая ширина уклонения (0,6):[1168 ] [1 149] [1 149] [1 168]ggplot(data = df, aes(x=group1, y = mean, fill = group2))+ geom_col(position = position_dodge(0.6), width = 0.5) + geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd), width = 0.9, position = position_dodge(0.6)) + ggtitle("another example")
Можно получить базовый URL от Фронтального контроллера Zend_Controller_Front::getInstance()->getBaseUrl();
. Я переношу это в помощника представления
class My_View_Helper_BaseUrl
{
/**
* Get base url
*
* @return string
*/
public function baseUrl()
{
return rtrim(Zend_Controller_Front::getInstance()->getBaseUrl(),'/');
}
}
Таким образом в разметке HTML у Вас есть что-то как <img src="<?php echo $this->baseUrl();?>/images/logo.png"/>
Запаздывающая наклонная черта разделяется в помощнике так, чтобы, когда приложение не запущено в sub папке (baseUrl пробел в этом случае) путь все еще работал.
Это мой помощник baseUrl :
class Zend_View_Helper_BaseUrl extends Zend_View_Helper_Abstract {
public function baseUrl() {
$protocol = isset($_SERVER['HTTPS']) ? 'https' : 'http';
$server = $_SERVER['HTTP_HOST'];
$port = $_SERVER['SERVER_PORT'] != 80 ? ":{$_SERVER['SERVER_PORT']}" : '';
$path = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\') . '/';
return "$protocol://$server$port$path";
}
}
<?php
/**
*
* @package TaMeR Library
* @copyright (C) 2010 Dennis T Kaplan
* @license GPL {@link http://www.gnu.org/licenses/gpl.html}
*
* @author Dennis T Kaplan
*/
/** @see Zend_View_Helper_Abstract */
require_once 'Zend/View/Helper/Abstract.php';
class TaMeR_View_Helper_BaseUrl extends Zend_View_Helper_Abstract {
/**
* Returns site's base url, or file with base url prepended
*
* $file is appended to the base url for simplicity
*
* @param string|null $file
* @return string
*/
public function baseUrl($file = NULL) {
$baseUrl = $domain = $subdomain = $protocol = $host = $port = NULL;
$host = array_reverse(explode('.', $_SERVER['HTTP_HOST']));
$domain = $host[1].'.'.$host[0];
$subdomain = (isset($host[2]) ? $host[2] : 'www');
if(getenv("HTTPS") == 'on') {
$protocol = 'https';
$port = $_SERVER['SERVER_PORT'] != 443 ? ':'.$_SERVER['SERVER_PORT'] : '';
}else{
$protocol = 'http';
$port = $_SERVER['SERVER_PORT'] != 80 ? ':'.$_SERVER['SERVER_PORT'] : '';
}
// Remove trailing slashes
if(NULL !== $file) {
$file = '/' . ltrim($file, '/\\');
}else{
$file = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/') . '/';
}
$baseUrl = $protocol.'://'.$subdomain.'.'.$domain.$port.$file;
return $baseUrl;
}
}